SQL更新语句中的新/旧变量

时间:2014-02-13 10:57:02

标签: oracle plsql database-trigger

如何更新旧行值。我使用过:old变量,但它对我不起作用。在这里我的代码,如果PID已经存在于项目表中,即(varProjectExists = 1),那么我更新付款期限。现在,如果付款期限为空,我想使用之前的paymnent期限​​值更新,否则新的付款期限已暂停

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 .....

1 个答案:

答案 0 :(得分:1)

OLD伪记录是指当前行的更新前状态,因此仅在updatedelete操作期间有意义。如果您要插入新记录,则没有“旧”状态可供参考。

根据您的评论,您要使用PROJECT表中已存在的先前付款条件值。这不会在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是唯一的,如果您使用MAXMIN并不重要,结果是相同的。 (如果它不是唯一的那么你必须决定使用哪个术语值,所以它可能是一个安全的假设。)