Oracle PL/SQL - Exemple avant le déclencheur UPDATE

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:

  1. La validation des données

  2. Mettre à jour les valeurs automatiquement

  3. 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:

  1. L'expérience professionnelle doit être supérieure ou égale à 3 ans et

  2. 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