我需要在历史数据表中插入'注册',当我在'ALUGUER'中插入内容时,触发器应在'HISTORICO'中插入一行:
我的触发器:
create or replace
trigger ADD_HISTORICO
AFTER INSERT
ON ALUGUER
FOR EACH ROW
DECLARE
cod_aluguer_p NUMBER(6,0);
cod_veiculo_p NUMBER(6,0);
BEGIN
SELECT ID_ALUGUER INTO cod_aluguer_p
FROM ALUGUER;
SELECT COD_VEICULO INTO cod_veiculo_p
FROM ALUGUER;
INSERT INTO HISTORICO(ID_ENTRADA,DESCRICAO,DATA_REGISTO,NOVO_VEICULO,NOVO_ALUGUER)
VALUES(SEQ_HISTORICO.nextval,'NOVA DESCRIÇÃO','21/11/2013',cod_veiculo_p,cod_aluguer_p);
END;
错误报告:
SQL错误:
ORA-04091:BDDAD_DL1.ALUGUER表是变异的,触发器可以 不读或修改 ORA-06512:在“BDDAD_DL1.ADD_HISTORICO”,第6行 ORA-04088:执行触发器'BDDAD_DL1.ADD_HISTORICO'时出错 04091. 00000 - 。 “表%s%s正在发生变异,触发/功能可能看不到它” *原因:触发器(或用户定义的plsql函数,在 这句话)试图查看(或修改)表格是否为
在被解雇它的声明修改的过程中 *动作:重写触发器(或函数),使其不读取该表。
答案 0 :(得分:2)
您正在尝试从触发器触发的表中读取记录。这是禁忌。所以,这段代码:
SELECT ID_ALUGUER INTO cod_aluguer_p
FROM ALUGUER;
SELECT COD_VEICULO INTO cod_veiculo_p
FROM ALUGUER;
是不允许的。而且,没有意义,因为select上没有WHERE子句,所以 将返回所有行。模仿点,无论如何你不能这样做。你想要做的是引用:触发行的新值istead。例如:
cod_aluguer_p := :new.ID_ALUGUER ;
cod_veiculo_p L= :NEW.COD_VEICULO;
此外,您甚至不需要那些局部变量,只需直接使用:new。
INSERT INTO HISTORICO(ID_ENTRADA,DESCRICAO,DATA_REGISTO,NOVO_VEICULO,NOVO_ALUGUER)
VALUES(SEQ_HISTORICO.nextval,'NOVA DESCRIÇÃO','21/11/2013',:NEW.COD_VEICULO,:new.ID_ALUGUER );
我建议您阅读Oracle docs on triggers
答案 1 :(得分:1)
不需要SELECT,只需参考触发器中的:NEW
值即可。此外,您可以使用TRUNC(SYSDATE)来获取当前日期,假设这是您的意图:
create or replace
trigger ADD_HISTORICO
AFTER INSERT
ON ALUGUER
FOR EACH ROW
BEGIN
INSERT INTO HISTORICO(ID_ENTRADA,DESCRICAO,DATA_REGISTO,
NOVO_VEICULO,NOVO_ALUGUER)
VALUES(SEQ_HISTORICO.nextval,'NOVA DESCRIÇÃO',
TRUNC(SYSDATE),:NEW.COD_VEICULO ,:NEW.ID_ALUGUER );
END;