我有以下方案(简化的)Oracle数据库: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个不同的参数第二个和第三个项目各有一个参数。
现在我需要在项目表中写入一个触发器,该表格会自动在params表中插入一个新的行,其中参数的类型为“4614”的参数值为给定的SCODE的最高值+1。
INSERT INTO Projects VALUES (1003,123)
...应该触发事件
INSERT INTO Parameters VALUES (5004,4614,1003,'02')
现在我有2种可能性,这两个不工作:
如果触发被声明为“之前”,我不能插入在参数表中,因为外键约束表明我还没有创建Project 1003的错误。在触发器内部进行提交是不可能的。
如果触发被声明为“后”,我得到一个错误
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只是没有选择的项目表,并返回正确的参数值。
你可以改变外键,以便它可以推迟;这样,直到你提交之后才会被检查。请记住,如果您正在进行批量更新,这可能会导致问题 - 直到交易结束时才会发生错误。或者,不要直接插入表中,而要通过存储过程来完成。这样,您就可以正确控制逻辑和流程,而无需执行任何花哨的解决方法。 – Boneist
@Boneist不幸的是我不能改变数据库系统的约束。为什么要将INSERT语句放入存储过程帮助?我的触发器触发器的内容就像v_new_param:= calculate_param();插入参数值(....,new.proj_id,v_new_param)。 –
如果您要编辑问题以添加脚本以创建触发器,那将会更好。 – Boneist