更新触发器正在更新多条记录而不是单条记录

Update Trigger is updating multiple records instead of single record

我是触发器的新手,在更新触发器期间遇到问题。 设想: 我有两个表 [table1 和 table2] 当 table1 中的特定列发生变化时,我需要根据几个条件更新 table2 记录

这是我的触发器,

create or replace TRIGGER UPDATE_TABLE1 
BEFORE UPDATE OF LOWTHRESHOLD, HIGHTHRESHOLD ON TABLE1 
for each row
  when(nvl(old.LOWTHRESHOLD,0) <> nvl(new.LOWTHRESHOLD,0) 
  OR  nvl(old.HIGHTHRESHOLD,0) <> nvl(new.HIGHTHRESHOLD,0))
  declare
  PID number(3) := nvl(:old.PID,0);
  oldLOWTH number(2) := nvl(:old.LOWTHRESHOLD,0);
  oldHIGHTH number(2) := nvl(:old.HIGHTHRESHOLD,0);
  newLOWTH number(2) := nvl(:new.LOWTHRESHOLD,0);
  newHIGHTH number(2) := nvl(:new.HIGHTHRESHOLD,0);
  ratio DOUBLE PRECISION;
  oldTHCrossed number(1) := 0;
  objID number(10) := 0;
  objType number(1) := 0;
   CURSOR profileUtil_Cursor  IS
        SELECT * FROM TABLE2 where upid = PID; 
  begin
    
  dbms_output.enable(1000);
 
  FOR v_record in profileUtil_Cursor LOOP
  ratio := v_record.UTILIZATIONRATIO;
  oldTHCrossed := v_record.THCROSSED;
  objID := v_record.objID;
  objType := v_record.objType;
 IF(ratio < newLOWTH AND ratio < newHIGHTH ) THEN
  UPDATE TABLE2 SET THCROSSED = 1, LASTUPDATED = date_to_miniseconds(sysdate) 
  WHERE objID = objID and objType = objType and upid = PID;
  ELSIF(newLOWTH <= ratio AND ratio <= newHIGHTH) THEN 
    UPDATE TABLE2 SET THCROSSED = 2, LASTUPDATED = date_to_miniseconds(sysdate) 
    WHERE objID = objID and objType = objType and upid = PID; 
  ELSIF(ratio > newHIGHTH) THEN
    UPDATE TABLE2 SET THCROSSED = 3, LASTUPDATED = date_to_miniseconds(sysdate)
    WHERE upid = PID and objID = objID and objType = objType; 
  END IF;
  END LOOP;
    IF SQL%NOTFOUND THEN
        DBMS_OUTPUT.put_line('NOT FOUND');
    END IF;
END;

但是当执行此触发器时,TABLE2 中的所有记录都在更新。 请提供一些解决此问题的建议。

光标选择 UPID = :OLD.PID 的所有行。根据您所说,table2 中的所有行都具有相同的 upid 列值,并且等于 table1.pid 正在现在更新].

UPDATE 语句将修改满足其 WHERE 条件的行。他们三个都是一样的:

      WHERE     objID = objID         --> that's 0
            AND objType = objType     --> that's 0 as well
            AND upid = PID            --> that's "old" table1.pid

这 - 除了我的第一个声明 - 意味着 table2 中的所有行不仅共享相同的 upid,而且它们的 objIDobjType 列值是0(至少,你是这样声明的)。

此外(正如@astentx 很好地观察到的那样),如果您将变量命名为与列名相同,它的行为就像您输入 where 1 = 1 一样,这始终为真。为局部变量使用前缀,例如l_ 所以 where 子句会变成

      WHERE     objID   = l_objID       --> that's 0
            AND objType = l_objType     --> that's 0 as well
            AND upid    = l_PID         --> that's "old" table1.pid

所以:如果以上一切都是真的,那么是的 - 触发器将更新 table2.

中的所有行