oracle 触发器 ORA-04091
Posted
技术标签:
【中文标题】oracle 触发器 ORA-04091【英文标题】:oracle trigger ORA-04091 【发布时间】:2016-07-04 16:09:43 【问题描述】:我已经创建了一个监视一张桌子的触发器。当用户将 Candidate_selected 列更改为 Y 时,我希望 oracle 从该表中提取列并将它们插入到一个查找表中,该表跟踪当前处于活动状态的候选者,即 ='Y'。 当我尝试更新该列时,我收到错误 ORA-04091。触发器不会更改构建它的表,我不知道为什么会出现此错误。 任何帮助将不胜感激 - 我去过几个网站但看不到修复,我想我已经盯着它太久了:)
CREATE OR REPLACE TRIGGER DEMO_SCHEMA.TRG_CANDIDATE_SELECTED
AFTER UPDATE OF CANDIDATE_SELECTED ON DEMO_SCHEMA.TBL_CANDIDATES FOR EACH ROW
BEGIN
IF :NEW.CANDIDATE_SELECTED = 'Y' THEN
INSERT INTO DEMO_SCHEMA.TBL_CANDIDATES_LKP
(UPDATED_DT, GROUP_ID, CAND_ID
,STAGE, STEP, EQUIPMENT, ORDER_REQ
,INCLUDED_IN_STUDY)
SELECT SYSDATE, GROUP_ID, CAND_ID, STAGE
,STEP, TRIM(REGEXP_SUBSTR(EQUIPMENT, '[^,]+', 1, LEVEL)) EQUIPMENT
,(CASE WHEN UPPER(ORDER_REQ) = 'FALSE' THEN 1
ELSE ROW_NUMBER() OVER (PARTITION BY GROUP_ID, CAND_ID, STAGE, STEP ORDER BY CAND_ID)
END) ORDER_REQ, INCLUDED_IN_STUDY
FROM (
SELECT GROUP_ID, CAND_ID
,STAGE, STEP, EQUIPMENT, EQUIPMENT EQUIP
,ORDER_REQ, INCLUDED_IN_STUDY
FROM DEMO_SCHEMA.TBL_CANDIDATES
WHERE GROUP_ID = :NEW.GROUP_ID
AND LOT_ID = :NEW.CAND_ID
AND STAGE = :NEW.STAGE
AND STEP = :NEW.STEP
)
CONNECT BY LEVEL <= REGEXP_COUNT(EQUIP,', ')+1;
ElSIF :NEW.CANDIDATE_SELECTED = 'N' THEN
UPDATE DEMO_SCHEMA.TBL_CANDIDATE_LKP
SET INCLUDED_IN_STUDY = :NEW.CANDIDATE_SELECTED
WHERE GROUP_ID = :NEW.GROUP_ID
AND CAND_ID = :NEW.CAND_ID
AND STAGE = :NEW.STAGE
AND STEP = :NEW.STEP;
END IF;
END TRG_CANDIDATE_SELECTED;
/
那里可能存在语法错误,但那是因为我在发布之前必须更改一些内容。此代码确实在 Oracle 中编译。 干杯。
【问题讨论】:
“ORA-04091”属于什么错误信息?请在错误编号旁边提供完整的错误消息;我们并不是所有关于 Oracle 错误编号及其相应错误消息的百科全书! *:-)tbl_candidates
上的行级触发器通常不允许查询tbl_candidates
。不知道你的数据模型,你真的需要查询tbl_candidates
还是只使用:new
伪记录中已经存在的数据?
@JustinCave 但是插入语句中的 tbl_candidates 与触发器打开的 tbl_candidates 的架构不同,假设 OP 没有在他们的示例代码中打错字。
@Boneist - 我假设这是“我在发布之前必须更改一些内容”评论的一部分。我猜它们是同一张表,并且修改了两个架构引用之一。
@JustinCave *:-) 我应该知道不要相信问题所说的! *;-)
【参考方案1】:
正如 Justin Cave 所建议的,您的问题是您从触发器所属的同一个表中进行选择。
如果由于需要在 EQUIPMENT 列中的每个项目有一行而需要将其保留为 insert as select 语句,那么您可以从 dual 中选择新值,如下所示:
CREATE OR REPLACE TRIGGER DEMO_SCHEMA.TRG_CANDIDATE_SELECTED
AFTER UPDATE OF CANDIDATE_SELECTED ON DEMO_SCHEMA.TBL_CANDIDATES FOR EACH ROW
BEGIN
IF :NEW.CANDIDATE_SELECTED = 'Y' THEN
INSERT INTO DEMO_SCHEMA.TBL_CANDIDATES_LKP
(UPDATED_DT, GROUP_ID, CAND_ID
,STAGE, STEP, EQUIPMENT, ORDER_REQ
,INCLUDED_IN_STUDY)
SELECT SYSDATE, GROUP_ID, CAND_ID, STAGE
,STEP, TRIM(REGEXP_SUBSTR(EQUIPMENT, '[^,]+', 1, LEVEL)) EQUIPMENT
,(CASE WHEN UPPER(ORDER_REQ) = 'FALSE' THEN 1
ELSE ROW_NUMBER() OVER (PARTITION BY GROUP_ID, CAND_ID, STAGE, STEP ORDER BY CAND_ID)
END) ORDER_REQ, INCLUDED_IN_STUDY
FROM (
SELECT :NEW.GROUP_ID group_id,
:NEW.CAND_ID cand_id,
:NEW.STAGE stage,
:NEW.STEP step,
:NEW.EQUIPMENT equipment,
:NEW.EQUIPMENT EQUIP,
:NEW.ORDER_REQ order_req,
:NEW.INCLUDED_IN_STUDY included_in_study
FROM dual
)
CONNECT BY LEVEL <= REGEXP_COUNT(EQUIP,', ')+1;
ElSIF :NEW.CANDIDATE_SELECTED = 'N' THEN
UPDATE DEMO_SCHEMA.TBL_CANDIDATE_LKP
SET INCLUDED_IN_STUDY = :NEW.CANDIDATE_SELECTED
WHERE GROUP_ID = :NEW.GROUP_ID
AND CAND_ID = :NEW.CAND_ID
AND STAGE = :NEW.STAGE
AND STEP = :NEW.STEP;
END IF;
END TRG_CANDIDATE_SELECTED;
/
【讨论】:
非常感谢 - 我会试一试以上是关于oracle 触发器 ORA-04091的主要内容,如果未能解决你的问题,请参考以下文章
仅在 old = new 上进行选择时获取变异表 (ORA-04091)