2016-07-04 6 views
0

Ich habe einen Trigger, der eine Tabelle überwacht. Wenn der Benutzer die Spalte candidate_selected in ein Y ändert, möchte ich, dass oracle Spalten aus dieser Tabelle hebt und sie in eine Nachschlagetabelle einfügt, die die aktuell aktiven Kandidaten verfolgt, d. H. "Y". Wenn ich versuche, die Spalte zu aktualisieren, erhalte ich den Fehler ORA-04091. Der Auslöser ändert nicht die Tabelle, auf der er erstellt wird, und ich bin fest, warum ich diesen Fehler bekomme. Jede Hilfe wäre sehr dankbar - ich habe ein paar Seiten und kann das Update nicht sehen, glaube, ich habe zu lange auf sie gestarrt :)Orakel-Trigger 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; 
/

Es gibt einen Syntaxfehler sein kann da aber musste ich ein paar Dinge ändern bevor ich gepostet habe. Dieser Code wird in Oracle kompiliert. Prost.

+0

Und zu welcher Fehlermeldung gehört "ORA-04091"? Bitte geben Sie die vollständige Fehlermeldung neben der Fehlernummer an. Wir laufen nicht alle Enzyklopädien mit Oracle-Fehlernummern und ihren entsprechenden Fehlermeldungen! * {: – Boneist

+1

Ein Trigger auf 'row-level' auf 'tbl_candidates' darf generell 'tbl_candidates' nicht abfragen. Wenn Sie Ihr Datenmodell nicht kennen, müssen Sie wirklich "tbl_candidates" abfragen oder können Sie einfach Daten verwenden, die bereits im ': new' Pseudo-Record enthalten sind? –

+0

@JustinCave aber die Tbl_Candidates in der Insert-Anweisung ist in einem anderen Schema zu den Tbl_Candidates der Trigger ist an, vorausgesetzt, das OP hat nicht einen Tippfehler in ihrem Beispiel-Code gemacht. – Boneist

Antwort

0

Wie von Justin Cave vorgeschlagen, besteht Ihr Problem darin, dass Sie aus derselben Tabelle auswählen, zu der Ihr Auslöser gehört.

Wenn Sie es als ein Einsatz als Select-Anweisung halten müssen aufgrund benötigen eine Zeile pro Element in der EQUIPMENT Spalte haben, dann können Sie nur die neuen Werte von Dual wählen, etwa so:

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; 
/
+0

Vielen Dank - Ich werde es versuchen –

+0

Funktioniert ein Vergnügen, danke an alle für Sie Hilfe. –