Oracle SQL update语句中的新/旧变量
如何更新旧的行值。我使用了:old变量,但它对我不起作用。在我的代码中,如果PID已经存在于项目表中,即(varProjectExists=1),那么我更新付款条件。现在,如果付款期限为空,我想用以前的付款期限值更新,否则将使用新的付款期限Oracle SQL update语句中的新/旧变量,oracle,plsql,database-trigger,Oracle,Plsql,Database Trigger,如何更新旧的行值。我使用了:old变量,但它对我不起作用。在我的代码中,如果PID已经存在于项目表中,即(varProjectExists=1),那么我更新付款条件。现在,如果付款期限为空,我想用以前的付款期限值更新,否则将使用新的付款期限 CREATE OR REPLACE TRIGGER TRIG_PROJECT_INSERT AFTER INSERT ON TEST_SYN_EAI_PROJECT_IN FOR EACH row DECLARE varError_Msg NVARCHA
CREATE OR REPLACE TRIGGER TRIG_PROJECT_INSERT AFTER
INSERT ON TEST_SYN_EAI_PROJECT_IN FOR EACH row DECLARE varError_Msg NVARCHAR2(100);
varSucceeded NVARCHAR2(1);
varActive_YN NVARCHAR2(50);
varProject_Id INT;
varPid INT ;
varPay_Term VARCHAR2(200);
varPay_Term1 VARCHAR2(200);
varError_id INT;
varCurr_activeyn INT;
varProjectExists NUMBER;
BEGIN
varError_Msg := 'No error';
varSucceeded := 'Y';
varError_id := 0;
varProjectExists := 0;
varPID := :new.pid;
varPay_Term := :new.ATTRIBUTE1;
varPay_Term1 := :old.ATTRIBUTE1;
varActive_YN := :new.active_yn;
varProject_ID := :new.project_id;
IF (NVL(varProject_Id,0) = 0 ) THEN
varError_Msg := 'project ID can not be null';
varSucceeded := 'N';
varError_id := 1;
END IF;
SELECT
CASE
WHEN (UPPER(varActive_YN) = 'ACTIVE'
OR UPPER(varActive_YN) = 'Y')
THEN 1
WHEN (UPPER(varActive_YN) = 'INACTIVE'
OR UPPER(varActive_YN) = 'N')
THEN 0
ELSE varcurr_activeyn
END
INTO varActive_YN
FROM Dual;
SELECT COUNT(1)
INTO varProjectExists
FROM project
WHERE ProjectUniversalID = varProject_ID;
IF (varProjectExists = 1) THEN
UPDATE project
SET PID = varPID,
PAYMENTTERM =
CASE
WHEN varPay_Term = 'NULL'
THEN varPay_Term1
WHEN varPay_Term IS NULL
THEN varPay_Term1
ELSE varPay_Term
END
ELSE .....
OLD
伪记录是指当前行的更新前状态,因此只有在update
或delete
操作期间才有意义。如果要插入新记录,则没有可参考的“旧”状态
从您的评论中,您希望使用项目表中已经存在的上一个付款条件值。这在OLD
中无论如何都不可用,因为它不是触发器所针对的表。如果是这种情况,那么您需要在检查它是否存在的同时检索它。比如:
CREATE OR REPLACE TRIGGER TRIG_PROJECT_INSERT
AFTER INSERT ON TEST_SYN_EAI_PROJECT_IN
FOR EACH ROW
DECLARE
...
BEGIN
...
varPay_Term := :new.ATTRIBUTE1;
-- varPay_Term1 := :old.ATTRIBUTE1; -- not valid
varActive_YN := :new.active_yn;
...
-- this doesn't need to select from dual, you can assign directly
varCurr_activeyn := CASE
WHEN (UPPER(varActive_YN) = 'ACTIVE'
OR UPPER(varActive_YN) = 'Y')
THEN 1
WHEN (UPPER(varActive_YN) = 'INACTIVE'
OR UPPER(varActive_YN) = 'N')
THEN 0
ELSE varCurr_activeyn
END CASE;
-- get the current term as you check if a record exists
SELECT COUNT(1), MAX(PAYMENTTERM)
INTO varProjectExists, varPay_Term1
FROM project
WHERE ProjectUniversalID = varProject_ID;
IF (varProjectExists = 1) THEN
UPDATE project
SET PID = varPID,
PAYMENTTERM =
CASE
WHEN varPay_Term = 'NULL'
THEN varPay_Term1
WHEN varPay_Term IS NULL
THEN varPay_Term1
ELSE varPay_Term
END
...
需要使用MAX()
,因为您已经在使用聚合COUNT()
,以避免ID不存在时出现“找不到数据”错误。假设ID是唯一的,那么无论使用MAX
还是MIN
,结果都是一样的。(如果它不是唯一的,那么您必须决定使用哪个术语值,因此这可能是一个安全的假设)。您不能更改“旧”值。您试图实现什么?无论如何,insert
触发器没有OLD
记录。(嗯,有,但一切都是空的)<代码>旧的
和新的
仅对更新有意义。您希望其中包含什么-您希望将varPay\u Term1
设置为什么,来自不同记录的值?实际上,问题标题指的是更新,但您在插入后创建了一个
触发器-您真正的意思是什么?如果付款条件为空,我想更新项目表中已经存在的以前的付款条件值,否则我希望新的付款条件来自表中的TEST\u SYN\u EAI\u PROJECT\u。我希望它能澄清,但这是在插入新记录时;更新现有版本时不需要?谢谢Alex。你很好地理解并澄清了情况