PL/SQL table 电平触发 运行 第二次更新后
PL/SQL table level trigger running after second update
我遇到这个问题,这个触发器在更新其他 table.The 中的一行后调用更新 table 的过程,问题是你必须更新 table STAVKARACUNA 两次到 table RACUN 更新,但它使用旧值。这是两者的代码:
这是一个程序的代码:
create or replace PROCEDURE ukupnaCenaRacun (SIF IN VARCHAR2) AS
SUMA float := 0;
suma2 float := 0;
Mesec NUMBER;
popust float :=0.1;
BEGIN
SELECT SUM(iznos) INTO SUMA
FROM STAVKARACUNA
WHERE SIF = SIFRARAC;
SELECT SUM(vredrobe*pdv) INTO SUMA2
FROM STAVKARACUNA
WHERE SIF = SIFRARAC;
SELECT EXTRACT (MONTH FROM DATUM) INTO Mesec FROM RACUN WHERE SIF=SIFRARAC;
IF(Mesec = 1) THEN
UPDATE RACUN
SET PDVIZNOS = SUMA2, ukupnozanaplatu = suma*(1-popust)
WHERE SIFRARAC=SIF;
END IF;
IF (MESEC != 1) THEN
UPDATE RACUN
SET PDVIZNOS = SUMA2, ukupnozanaplatu = suma
WHERE SIFRARAC=SIF;
END IF;
END;
这是一个触发器:
create or replace TRIGGER "UKUPNACENA_RACUN_UKUPNO"
AFTER INSERT OR UPDATE OR DELETE OF CENA,KOL,PDV ON STAVKARACUNA
DECLARE
SIF VARCHAR2(20) := PACKAGE_STAVKARACUNA.SIFRARAC;
BEGIN
PACKAGE_STAVKARACUNA.ISKLJUCI_TRIGER('FORBID_UPDATING');
ukupnaCenaRacun(SIF);
PACKAGE_STAVKARACUNA.UKLJUCI_TRIGER('FORBID_UPDATING');
END;
问题是当更新 table STAVKARACUNA 时,table RACUN 没有任何反应,但是下次 table STAVKARACUNA 更新时 table RACUN 中的数据是已更新但具有旧值。
非常感谢。
您是否知道 table 上的事件触发器不应直接访问 table?代码在 一个 DML 事件中。 table 正处于被更改的中间。因此,任何返回到相同 table 的查询都可能会尝试读取正在更改的数据。它可能会尝试读取在执行提交之前并不完全存在的数据,或者现在是一个值但一旦执行提交将成为不同的值。 table 是 变异 。
这适用于触发器调用的触发器之外的任何代码。所以 ukupnaCenaRacun
过程是在触发器的上下文中执行的。然而它出去并在两个地方查询 table STAVKARACUNA
(可以放在一个查询中但既不在这里也不在那里)。
由于您没有收到变异 table 错误,我只能假设在提交触发事件之后才会进行更新,但是直到 [=之后您才会看到结果=26=]那个稍后提交——就像提交第二次更新时一样。
这个解释对我来说实际上听起来很空洞,因为我一直认为触发器执行的 all activity 作为一个事务的一部分提交或回滚。但这就是你描述的动作。
SIF
似乎是包规范中定义的包变量。由于过程中的所有内容都关闭该值并且触发器不会更改该值,因此不能将 SUMA
和 SUMA2
也定义为变量,值在 SIF
更改时更新?
我遇到这个问题,这个触发器在更新其他 table.The 中的一行后调用更新 table 的过程,问题是你必须更新 table STAVKARACUNA 两次到 table RACUN 更新,但它使用旧值。这是两者的代码:
这是一个程序的代码:
create or replace PROCEDURE ukupnaCenaRacun (SIF IN VARCHAR2) AS
SUMA float := 0;
suma2 float := 0;
Mesec NUMBER;
popust float :=0.1;
BEGIN
SELECT SUM(iznos) INTO SUMA
FROM STAVKARACUNA
WHERE SIF = SIFRARAC;
SELECT SUM(vredrobe*pdv) INTO SUMA2
FROM STAVKARACUNA
WHERE SIF = SIFRARAC;
SELECT EXTRACT (MONTH FROM DATUM) INTO Mesec FROM RACUN WHERE SIF=SIFRARAC;
IF(Mesec = 1) THEN
UPDATE RACUN
SET PDVIZNOS = SUMA2, ukupnozanaplatu = suma*(1-popust)
WHERE SIFRARAC=SIF;
END IF;
IF (MESEC != 1) THEN
UPDATE RACUN
SET PDVIZNOS = SUMA2, ukupnozanaplatu = suma
WHERE SIFRARAC=SIF;
END IF;
END;
这是一个触发器:
create or replace TRIGGER "UKUPNACENA_RACUN_UKUPNO"
AFTER INSERT OR UPDATE OR DELETE OF CENA,KOL,PDV ON STAVKARACUNA
DECLARE
SIF VARCHAR2(20) := PACKAGE_STAVKARACUNA.SIFRARAC;
BEGIN
PACKAGE_STAVKARACUNA.ISKLJUCI_TRIGER('FORBID_UPDATING');
ukupnaCenaRacun(SIF);
PACKAGE_STAVKARACUNA.UKLJUCI_TRIGER('FORBID_UPDATING');
END;
问题是当更新 table STAVKARACUNA 时,table RACUN 没有任何反应,但是下次 table STAVKARACUNA 更新时 table RACUN 中的数据是已更新但具有旧值。 非常感谢。
您是否知道 table 上的事件触发器不应直接访问 table?代码在 一个 DML 事件中。 table 正处于被更改的中间。因此,任何返回到相同 table 的查询都可能会尝试读取正在更改的数据。它可能会尝试读取在执行提交之前并不完全存在的数据,或者现在是一个值但一旦执行提交将成为不同的值。 table 是 变异 。
这适用于触发器调用的触发器之外的任何代码。所以 ukupnaCenaRacun
过程是在触发器的上下文中执行的。然而它出去并在两个地方查询 table STAVKARACUNA
(可以放在一个查询中但既不在这里也不在那里)。
由于您没有收到变异 table 错误,我只能假设在提交触发事件之后才会进行更新,但是直到 [=之后您才会看到结果=26=]那个稍后提交——就像提交第二次更新时一样。
这个解释对我来说实际上听起来很空洞,因为我一直认为触发器执行的 all activity 作为一个事务的一部分提交或回滚。但这就是你描述的动作。
SIF
似乎是包规范中定义的包变量。由于过程中的所有内容都关闭该值并且触发器不会更改该值,因此不能将 SUMA
和 SUMA2
也定义为变量,值在 SIF
更改时更新?