2016-06-23 12 views
0

Ich habe die unten Trigger erstellt, aber es ist nicht immer gefeuert, nachdem ich auf den erwähnten Tabelle in neue insert/update tue:Wie erstellt man einen Trigger, der ausgelöst wird, wenn ein Einfügen oder Aktualisieren in einer Tabelle erfolgt?

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details 
AFTER 
INSERT OR UPDATE --of emp_email_address, ssn_nb 
ON ref_adp_employees 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
BEGIN 
     UPDATE ref_adp_employees 
     SET emp_email_address = 'QA_' ||emp_email_address, 
      ssn_nb = nvl2(ssn_nb, NULL, '123-45-6789') 
     WHERE upper(emp_email_address) NOT LIKE 'QA_%' 
     AND upper(emp_email_address) LIKE '%@KEENAN.COM'; 
exception 
     WHEN others 
      THEN 
       NULL; 
END; 

Kann mir bitte jemand vorschlagen, was ich fehle?

+1

Warum fangen Sie die Ausnahme WHEN OTHERS ab und tun nichts dagegen. Entfernen Sie vorerst Ihren Ausnahmeabschnitt und kompilieren Sie den Trigger erneut. Führen Sie eine Einfügung/Aktualisierung durch und prüfen Sie, ob ein Fehler vorliegt. –

+0

Auch Ihre Update-Anweisung scheint ein statisches Update zu sein. Sie verwenden keine Werte in dem neu erstellten oder aktualisierten Datensatz in Ihrem Trigger. Was genau willst du mit diesem Auslöser erreichen? –

+0

@phonetic_man: Lassen Sie mich die erste Bedingung überprüfen, nach der Sie mich gefragt haben, nachdem Sie den Ausnahmeabschnitt entfernt haben. Ich möchte diesen Trigger auslösen, wenn ein neuer Datensatz eingefügt oder ein vorhandener Datensatz aktualisiert wird. –

Antwort

0

Haben Sie schon einmal von Google gehört? Es gibt eine Vielzahl von Antworten und Beispielen für Trigger, aber einige Dinge, die ich zu diesem Zeitpunkt sehe:

1) Trigger ändern, bevor Einfügen oder zu aktualisieren. Verwenden Sie AFTER, wenn Sie Änderungen an einer anderen Tabelle vornehmen oder einen nachfolgenden Prozess in der Tabelle ausführen.

2) Entfernen Sie den Kommentar zu den einzelnen Feldern, die geändert oder hinzugefügt werden. Das war gutes AFAIK.

3) In Ihrem Körper des Auslösers verwenden, WENN SIE EINFÜGEN und WENN AKTUALISIEREN. Oder wenn Sie nur die Tabelle aktualisieren, ändern Sie DDL nur zu VOR UPDATE.

4) Im Update Referenz mit set: new.emp_email_address = 'QA_' || : old.emp_email_address ... und so weiter und so fort. Hier wird das Alte als alt und neu wie neu wichtig.

+0

werden versuchen, mit dem vierten Punkt –

+0

ich versucht: Erstellen oder TRIGGER ref_upd_user_phi_details VOR INSERT oder UPDATE ausgebrauchte emp_email_address, ssn_nb AUF ref_adp_employees REFERENCING ALT WIE alt NEW AS neue FÜR JEDE REIHE BEGIN UPDATE HR ersetzen. ref_adp_employees SET: new.emp_email_address = 'QA_' ||: alt.emp_email_adresse, : neu.ssn_nb = nvl2 (: alt.ssn_nb, NULL, '123-45-6789') WHERE oben (: old.emp_email_adresse) NICHT wie 'QA_%' AND obere (: old.emp_email_address) LIKE '%@KEENAN.COM'; --ausnahme - WANN andere - DANN - NULL; ENDE; –

0

Bitte überprüfen Sie, ob der Trigger gültig ist oder nicht, indem Sie die folgende Abfrage Brennen ..

SELECT * 
FROM ALL_OBJECTS 
WHERE OBJECT_NAME = trigger_name 
AND OBJECT_TYPE = 'TRIGGER' 
AND STATUS <> 'VALID' 

Der Trigger feuert nach dem Update .. versuchen, bevor Update

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details 
Before 
INSERT OR UPDATE 
+0

Vielen Dank für die Freigabe der Abfrage. Auch, wenn Sie vorschlagen könnten, was ich vermisse, wenn ich den oben genannten Auslöser erstelle. –

1

Wie @phonetic_man hingewiesen out, verstecken Sie alle Fehler, die Sie bekommen, indem Sie when others fangen und keine Maßnahmen ergreifen. Ohne den Ausnahmeblock würden Sie sehen, dass Sie einen mutierenden Tabellenfehler verursachen (ORA-04091), weil Sie sich auf die gleiche Tabelle beziehen, gegen die der Trigger gerichtet ist.

Wenn Sie den for each row Teil herausgenommen haben, um ihn in einen Auslöser auf Anweisungsebene zu verwandeln, würden Sie dieses Problem vermeiden, aber jetzt hätten Sie eine Endlosschleife (ORA-00036) - wenn Sie versuchen, die Tabelle von innen zu aktualisieren der Auslöser, der selbst aktualisiert, bewirkt, dass derselbe Auslöser erneut ausgelöst wird; die versucht, die gleiche Tabelle noch einmal zu aktualisieren, wodurch der Auslöser erneut ausgelöst wird; usw., bis Oracle den Prozess bemerkt und beendet.

Es wäre sinnvoller, einen Trigger auf Zeilenebene vor dem Einfügen zu verwenden, um sicherzustellen, dass die neuen Werte für die Zeile mit dem Muster übereinstimmen, das Sie erzwingen möchten. Vielleicht so etwas wie:

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details 
BEFORE INSERT OR UPDATE --of emp_email_address, ssn_nb 
ON ref_adp_employees 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
BEGIN 
    IF upper(:NEW.emp_email_address) NOT LIKE 'QA_%' 
     AND upper(:NEW.emp_email_address) LIKE '%@KEENAN.COM' 
    THEN 
     :NEW.emp_email_address := 'QA_' || :NEW.emp_email_address; 
     :NEW.ssn_nb := CASE WHEN :NEW.ssn_nb IS NULL THEN '123-45-6789' END; 
    END IF; 
END; 
/

Und um zu sehen, was es tut:

insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (1, 'TEST_1', '123-45-6789'); 
insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (2, '[email protected]', '123-45-9876'); 
insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (3, 'QA_TEST_1', null); 

select emp_id, emp_email_address, ssn_nb from ref_adp_employees; 

    EMP_ID EMP_EMAIL_ADDRESS    SSN_NB  
---------- ------------------------------ ----------- 
     1 TEST_1       123-45-6789 
     2 [email protected]      
     3 QA_TEST_1         

Nicht sicher, ob Sie wirklich Set SSNs mit null und schalten nulls in den festen Wert ersetzen soll; Ich vermute, dass Sie wirklich Sollwerte mit dem festen Zeichenfolge zu ersetzen versuchen und Blätter nulls allein, in diesem Fall wäre es:

 :NEW.ssn_nb := CASE WHEN :NEW.ssn_nb IS NOT NULL THEN '123-45-6789' END; 

Vielleicht möchten Sie auch bewegen, dass außerhalb des IF Block, so ist es geschafft, unabhängig davon, Die E-Mail Adresse; Ich habe repliziert, was Ihr ursprünglicher Code versucht hat, aber das könnte nicht richtig sein.

Wenn vorhandene Daten geändert werden müssen, um diese Änderungen zu berücksichtigen, führen Sie eine einmalige Aktualisierung der gesamten Tabelle durch - versuchen Sie nicht, dies innerhalb eines Triggers zu tun.

+0

Das funktioniert jetzt gut: CREATE OR TRIGGER ref_upd_user_phi_details VOR INSERT OR UPDATE von emp_email_address, ssn_nb AUF ref_adp_employees REFERENCING ALT WIE ALT NEU WIE NEU FÜR JEDE REIHE BEGIN IF oberen REPLACE (: NEW.emp_email_address) NOT LIKE 'QA_%' UND oben (: NEW.emp_email_address) WIE '% @KEENAN.COM' THEN : NEW.emp_email_address: = 'QA_' || : NEW.emp_email_adresse; : NEW.ssn_nb: = FALL WENN: NEW.ssn_nb NICHT NULL DANN '123-45-6789' END; ENDE IF; : NEW.ssn_nb: = FALL WENN: NEW.ssn_nb NICHT NULL DANN '123-45-6789' END; ENDE; –

+0

@Oracle_UNIX_aspirant - das ist nicht wirklich hilfreich für jemand anderen, und es ist schwer, Code (oder seine Relevanz) als Kommentar zu lesen. Sie scheinen die 'ssn_nb'-Änderung wieder eingefügt zu haben, so dass sie für alle Updates/Inserts gilt; Sie brauchen es auch nicht im 'IF'-Block. –