Oracle PL / SQL - Exemple de déclencheur avant UPDATE
Cet article vous montre comment utiliserBEFORE UPDATE TRIGGER
, il se déclenche avant que l’opération de mise à jour ne soit exécutée. Dans les scénarios de la vie réelle, il est principalement utilisé à des fins telles que:
-
La validation des données
-
Mettre à jour les valeurs automatiquement
-
Enregistrement des données ou audit
1. La validation des données
Supposons que certaines entreprises aient des offres d'emploi et disposent déjà de données de candidature et que les critères soient:
-
L'expérience professionnelle doit être supérieure ou égale à 3 ans et
-
La tentative d'application précédente ne doit pas être effectuée au cours des 2 dernières années.
Pour assurer l'intégrité des données, nous créerons le déclencheurBEFORE UPDATE
et il limitera UPDATE sur les données qui violent l'un des critères ci-dessus.
1.1 First, we will create table job_openings.
jobs_ouvertures
--Creating job_openings table. CREATE TABLE job_openings ( APPLICATION_ID number(10) primary key, FIRST_NAME varchar2(50), LAST_NAME varchar2(50), JOB_EXPERIENCE number(2), LAST_APPLIED_DATE date );
1.2 Then we will create a before update tigger on column JOB_EXPERIENCE
and LAST_APPLIED_DATE
of job_openings table.
trg_before_emp_update
-- Creating TRIGGER CREATE OR REPLACE TRIGGER trg_before_emp_update BEFORE UPDATE OF JOB_EXPERIENCE,LAST_APPLIED_DATE on job_openings FOR EACH ROW DECLARE years_since_last_applied number(5); BEGIN years_since_last_applied := -1; IF(:NEW.LAST_APPLIED_DATE IS NOT NULL) THEN SELECT MONTHS_BETWEEN(TO_DATE(sysdate,'DD-MON-YYYY'), TO_DATE(:NEW.LAST_APPLIED_DATE,'DD-MON-YYYY'))/12 INTO years_since_last_applied FROM dual; -- Check whether years_since_last_applied is greater than 2 years or not IF (years_since_last_applied <= 2) THEN RAISE_APPLICATION_ERROR(-20000,'Previous application attempt must not be done in last 2 years.'); END IF; END IF; -- Job experience must be more than or equal to 3 years. IF(:new.JOB_EXPERIENCE < 3) THEN RAISE_APPLICATION_ERROR(-20000,'Job experience must be more than or equal to 3 years.'); END IF; END;
1.3 Normal Data.
-- setting date format to to 'DD-MON-YYYY' alter session set nls_date_format = 'DD-MON-YYYY'; INSERT INTO job_openings VALUES (1,'Mark','Sharma',10,'01-JAN-2012'); INSERT INTO job_openings VALUES (2,'Praveen','Kumar',4,'01-DEC-2010'); INSERT INTO job_openings VALUES (3,'Rahul','Kohli',6,null); -- output 1 rows inserted. 1 rows inserted. 1 rows inserted.
select * from job_openings;
ID D'APPLICATION |
PRÉNOM |
NOM DE FAMILLE |
EXPÉRIENCE DE TRAVAIL |
LAST_APPLIED_DATE |
1 |
Mark |
Sharma |
10 |
01-JAN-2012 |
2 |
Praveen |
Kumar |
4 |
01-DÉC-2010 |
3 |
Rahul |
Kohli |
6 |
null |
1.4 Test Trigger raise error – Job experience must be more than or equal to 3 years.
-- Try to update job_experience less than 3 years UPDATE job_openings SET JOB_EXPERIENCE = 2 where APPLICATION_ID = 1; -- error Error report - ORA-20000: Job experience must be more than or equal to 3 years. ORA-06512: at "SYSTEM.TRG_BEFORE_EMP_UPDATE", line 21 ORA-04088: error during execution of trigger 'SYSTEM.TRG_BEFORE_EMP_UPDATE'
1.5 Test Trigger raise error – Previous application attempt must not be done in last 2 years.
-- Try to update last_Applied_Date which is less than 2 years UPDATE job_openings SET LAST_APPLIED_DATE = '10-JUN-2016' where APPLICATION_ID = 3; -- error Error report - ORA-20000: Previous application attempt must not be done in last 2 years. ORA-06512: at "SYSTEM.TRG_BEFORE_EMP_UPDATE", line 15 ORA-04088: error during execution of trigger 'SYSTEM.TRG_BEFORE_EMP_UPDATE'
2. Mettre à jour les valeurs
Un exemple de déclenchement deBEFORE UPDATE
pour mettre à jour automatiquement:NEW.UPDATED_BY
et:NEW.UPDATED_DATE
.
2.1 Create a table.
person_records
--Creating person_records table. CREATE TABLE person_records ( PERSON_ID number(10) primary key, FIRST_NAME varchar2(50), LAST_NAME varchar2(50), HIRE_DATE date, UPDATED_BY varchar2(20), UPDATED_DATE date );
2.2 Create a before update trigger on table person_records
trg_before_person_update
CREATE OR REPLACE TRIGGER trg_before_person_update BEFORE UPDATE on person_records FOR EACH ROW DECLARE username varchar2(20); BEGIN SELECT USER INTO username FROM dual; -- Setting updated_by and updated_Date values. :NEW.UPDATED_BY := username; :NEW.UPDATED_DATE := sysdate; END;
2.3 Insert two records.
-- setting date format to to 'DD-MON-YYYY' alter session set nls_date_format = 'DD-MON-YYYY'; INSERT INTO person_records VALUES (101,'Devil','Khedut',sysdate,null,null); INSERT INTO person_records VALUES (102,'Kanji','Yadav',sysdate,null,null); -- output 1 rows inserted. 1 rows inserted.
select * from person_records;
PERSON_ID |
PRÉNOM |
NOM DE FAMILLE |
DATE D'EMBAUCHE |
MIS À JOUR PAR |
UPDATED_DATE |
101 |
Diable |
Khedut |
06-JUIN-2017 |
null |
null |
102 |
Kanji |
Yadav |
06-JUIN-2017 |
null |
null |
2.4 Update records and it will fires the before update trigger. Les valeurs deUPDATED_BY
etUPDATED_DATE
seront mises à jour automatiquement.
UPDATE person_records SET first_name = 'Lavji' WHERE person_id = 101; UPDATE person_records SET first_name = 'Jogi' WHERE person_id = 102; -- output 1 rows updated. 1 rows updated.
select * from person_records;
PERSON_ID |
PRÉNOM |
NOM DE FAMILLE |
DATE D'EMBAUCHE |
MIS À JOUR PAR |
UPDATED_DATE |
101 |
Lavji |
Khedut |
06-JUIN-2017 |
HR |
06-JUIN-2017 |
102 |
Jogi |
Yadav |
06-JUIN-2017 |
HR |
06-JUIN-2017 |
3. Logging/Auditing data
Dans cet exemple, nous avons créé un déclencheur qui insérera des lignes dans une table d'audit avant chaque mise à jour de la table de transaction. Chaque fois que l'utilisateur UPDATE des données debank_transactions
, les anciennes données seront insérées dansbank_transactions_audit
par déclencheur à des fins d'audit ou de sauvegarde.
3.1 Create a bank transaction table.
bank_transactions
--Creating bank_transactions table. CREATE TABLE bank_transactions ( TXN_ID number(10) primary key, TXN_NUMBER varchar2(20), PARTY_NAME varchar2(50), TXN_DATE date, CREATED_BY varchar2(20), CREATED_DATE date );
3.2 Create another bank transaction audit table.
bank_transactions_audit
--Creating bank_transactions_audit table. CREATE TABLE bank_transactions_audit ( TXN_ID number(10), TXN_NUMBER varchar2(20), PARTY_NAME varchar2(50), TXN_DATE date, CREATED_BY varchar2(20), CREATED_DATE date );
3.3 Create a before update trigger on bank_transactions
table.
trg_before_update_txn_audit
--Creating Trigger CREATE OR REPLACE TRIGGER trg_before_update_txn_audit BEFORE UPDATE ON bank_transactions FOR EACH ROW BEGIN -- Insert OLD values in audit table for logging purpose INSERT INTO bank_transactions_audit VALUES(:OLD.TXN_ID,:OLD.TXN_NUMBER, :OLD.PARTY_NAME,:OLD.TXN_DATE,:OLD.CREATED_BY,:OLD.CREATED_DATE); END;
3.4 Insert some records.
--Inserting values INSERT INTO BANK_TRANSACTIONS values ('1','TXN1234','Peter Thomas','12-MAY-2017','HR',sysdate); INSERT INTO BANK_TRANSACTIONS values ('2','TXN9999','Jemes Patel','10-JUN-2016','HR',sysdate); select * from BANK_TRANSACTIONS;
TXN_ID |
TXN_NUMBER |
NOM DE LA FÊTE |
TXN_DATE |
CRÉÉ PAR |
CREATED_DATE |
1 |
TXN1234 |
Peter Thomas |
12-MAI-2017 |
HR |
06-JUIN-2017 |
2 |
TXN9999 |
Jemes Patel |
10-JUIN-2016 |
HR |
06-JUIN-2017 |
3.5 Insert operation didn’t fire the before update trigger.
select * from BANK_TRANSACTIONS_AUDIT; -- output no rows selected.
3.6 Update records, it will fires the "before update" trigger and insert the old data into another audit table.
--updating values. UPDATE bank_transactions SET txn_number = 'NEWTXN8080' WHERE txn_id = 1; UPDATE bank_transactions SET txn_number = 'NEWTXN9595' WHERE txn_id = 2; -- output 1 rows updated. 1 rows updated.
select * from BANK_TRANSACTIONS;
TXN_ID |
TXN_NUMBER |
NOM DE LA FÊTE |
TXN_DATE |
CRÉÉ PAR |
CREATED_DATE |
1 |
NOUVEAUTXN8080 |
Peter Thomas |
12-MAI-2017 |
HR |
06-JUIN-2017 |
2 |
NOUVEAUTXN9595 |
Jemes Patel |
10-JUIN-2016 |
HR |
06-JUIN-2017 |
select * from BANK_TRANSACTIONS_AUDIT;
TXN_ID |
TXN_NUMBER |
NOM DE LA FÊTE |
TXN_DATE |
CRÉÉ PAR |
CREATED_DATE |
1 |
TXN1234 |
Peter Thomas |
12-MAI-2017 |
HR |
06-JUIN-2017 |
2 |
TXN9999 |
Jemes Patel |
10-JUIN-2016 |
HR |
06-JUIN-2017 |
Références
-
https://docs.oracle.com/cloud/latest/db112/LNPLS/create_trigger.htm#LNPLS01374 [Oracle
-
Instruction CREATE TRIGGER]
-
-
https://docs.oracle.com/cloud/latest/db112/LNPLS/triggers.htm#LNPLS020 [Oracle
-
PL/SQL Triggers]
-