Oracle SQL update语句中的新/旧变量

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

如何更新旧的行值。我使用了: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 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。你很好地理解并澄清了情况