我正在使用以下Scenario(简化)的Oracle数据库:
Projects Params
------------- -----------
PROJ_ID SCODE PARAM_ID PARAM_TYPE PROJ_ID PARAM_VALUE
1000 123 5000 4614 1000 '00'
1001 124 5001 4610 1000 'Micro'
1002 123 5002 4614 1001 '02'
5003 4614 1002 '01'
这意味着,3个项目 - 项目1000有2个不同的参数,第二个和第三个项目各有一个参数。
现在我需要在projects表上编写一个Trigger,它会自动在params表中插入一个新行,该行具有给定SCODE类型为“4614”的参数的最大值+1。
INSERT INTO Projects VALUES (1003,123)
...应触发事件
INSERT INTO Parameters VALUES (5004,4614,1003,'02')
现在我有两种可能性,两种都不起作用:
如果触发器被声明为“BEFORE”,我无法在Parameters表中插入,因为外键约束显示了一个错误,即尚未创建Project 1003。无法在触发器内执行提交。
如果触发器被声明为“AFTER”,则会出现错误
ORA-04091: table name is mutating, trigger/function may not see it
因为我正在访问现在触发的表格。
必须有解决此问题的方法。 任何帮助表示赞赏!
//修改
我的触发器:
CREATE OR REPLACE TRIGGER PROJ_ARI_TRIGGER
AFTER INSERT
ON PROJECTS
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_param VARCHAR2(10);
BEGIN
v_param := get_next_param_val(:new.SCODE);
INSERT INTO Parameters(<<sequence>>,4614,:new.PROJ_ID,v_param);
END PROJ_ARI_TRIGGER;
函数get_next_param_val只是选择项目表并返回正确的参数值。
答案 0 :(得分:0)
Darned变异表!包裹的时间。
CREATE OR REPLACE PACKAGE no_mutation_pkg
AS
procedure set_val(pVal number);
function get_val return number;
END;
/
CREATE OR REPLACE PACKAGE BODY no_mutation_pkg
AS
g_val number;
procedure set_val(pVal number)
IS
BEGIN
g_val := pVAl;
END;
function get_val return number
IS BEGIN
return g_val;
end;
END;
然后创建一个BEFORE插入触发器,计算该值并使用set_val将其存储在包中,AFTER insert触发器使用GET_VAL检索该值并执行插入。
编辑:根据贾斯汀对重复的评论,你肯定需要考虑这一点。坦率地说,当你需要跳过这样的箍时,数据架构通常是可疑的
答案 1 :(得分:0)
我找到了解决问题的方法!
使用复合触发器,我可以先在SCODE中获取最大值并计算参数值(在每行之前)
然后在param表中插入值(在每行之后)
谢谢@Bob Jarvis