oracle触发器ORA-04091

时间:2016-07-04 16:09:43

标签: oracle plsql oracle11g

我有一个触发器看着一张桌子。当用户将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中编译。 欢呼声。

1 个答案:

答案 0 :(得分:0)

根据Justin Cave的建议,您的问题是您从触发器所属的同一个表中进行选择。

如果由于需要在EQUIPMENT列中为每个项目添加一行而需要将其作为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;
/