更新触发器正在更新多条记录而不是单条记录
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
,而且它们的 objID
和 objType
列值是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
.
中的所有行
我是触发器的新手,在更新触发器期间遇到问题。 设想: 我有两个表 [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
,而且它们的 objID
和 objType
列值是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
.