【问题标题】:New/Old variable in SQL update statementSQL 更新语句中的新/旧变量
【发布时间】:2014-02-13 10:57:01
【问题描述】:

如何更新旧行值。我使用了 :old 变量,但它对我不起作用。在我的代码中,如果项目表中已经存在 PID,即 (varProjectExists = 1),那么我会更新付款期限。现在,如果付款期限为 null ,我想用以前的付款期限值更新,否则新的付款期限是飞行

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

【问题讨论】:

  • 您无法更改“旧”值。你想达到什么目的?
  • 无论如何,insert 触发器没有 OLD 记录。 (嗯,有,但一切都是空的)。 OLDNEW 仅对 update 有意义。您希望其中包含什么 - 您希望将 varPay_Term1 设置为什么,来自不同记录的值?实际上问题标题是指更新,但您正在创建一个 after insert 触发器 - 您的真正意思是什么?
  • 如果付款期限为空,我想更新 PROJECT 表中已经存在的先前付款期限值,否则我希望新的付款期限来自 TEST_SYN_EAI_PROJECT_IN 表。我希望它澄清。
  • 但这是插入新记录的时候;不是在更新现有的时候?

标签: oracle plsql database-trigger


【解决方案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 不存在时出现 no-data-found 错误。假设ID是唯一的,不管你用MAX还是MIN,结果都是一样的。 (如果它不是唯一的,那么您必须决定使用哪个术语值,所以这可能是一个安全的假设。

【讨论】:

  • 谢谢亚历克斯。您很好地理解并澄清了情况
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
相关资源
最近更新 更多