Oracle 触发器中的“坏绑定变量”

Oracle 触发器中的“坏绑定变量”,oracle,plsql,triggers,Oracle,Plsql,Triggers,我使用SQL Developer编写的代码与以下触发器相关时出现问题: CREATE OR REPLACE TRIGGER AGGIORNA_QTA AFTER INSERT ON ACQUISTI FOR EACH ROW BEGIN update prodotti set qta=:old.qta-(select qtaacq from acquisti where utente=:new.utente and prodotto=:new.prodotto and data

我使用SQL Developer编写的代码与以下触发器相关时出现问题:

CREATE OR REPLACE TRIGGER AGGIORNA_QTA 
AFTER INSERT ON ACQUISTI 
FOR EACH ROW 
BEGIN
  update prodotti set qta=:old.qta-(select qtaacq from acquisti
    where utente=:new.utente and prodotto=:new.prodotto and data=:new.data);
END;
这是数据库表定义:

CREATE TABLE PRODOTTI(  
 CODICE NUMBER, 
 NOME VARCHAR2(10), 
 QTA NUMBER, 
 PREZZO NUMBER, 
 PRIMARY KEY ("CODICE"))

CREATE TABLE UTENTI(
 USERNAME VARCHAR2(10), 
 NOME VARCHAR2(10), 
 COGNOME VARCHAR2(10), 
 PRIMARY KEY ("USERNAME"))

CREATE TABLE ACQUISTI(
 UTENTE VARCHAR2(10), 
 PRODOTTO NUMBER, 
 DATA DATE, 
 QTAACQ NUMBER, 
 PRIMARY KEY (UTENTE,PRODOTTO,DATA),
 FOREIGN KEY (UTENTE) REFERENCES UTENTI (USERNAME),
 FOREIGN KEY (PRODOTTO) REFERENCES PRODOTTI (CODICE)) 
问题是,我一直得到以下错误:

Error(2,29): PLS-00049: bad bind variable 'OLD.QTA'

我做错了什么?

问题是您试图在错误的表中设置变量,ACQUISTI没有一个名为qta的列,但PRODOTTI表有一个名为qta的列

旧的和新的伪行只存在于触发器所针对的表中。对于要更新的表,您可以直接参考qta,它将使用当前值进行计算:

update prodotti set qta = qta - ...
您也没有指定要更新该表中的哪一行,因此需要添加以下内容:

where codice = :new.prodotto
但是,当您试图从插入的同一个表中进行选择时,会出现ORA-04091变异表错误。当您基于主键进行查询时,您不能期望返回多行,因此根本不需要查询,只需使用新行的qtaacq值即可

您可能会发现,在多用户环境中,这并不像您期望的那样可靠地维护主表中的数量。同时插入可能会看到相同的旧qta值,并导致更新丢失

CREATE OR REPLACE TRIGGER AGGIORNA_QTA 
AFTER INSERT ON ACQUISTI 
FOR EACH ROW 
BEGIN
  update prodotti set qta = qta - :new.qtaacq
  where codice = :new.prodotto;
END;
/