Oracle PL/SQL - Vor dem UPDATE-Trigger-Beispiel

Oracle PL / SQL - Vor dem UPDATE Trigger-Beispiel

Dieser Artikel zeigt Ihnen, wie SieBEFORE UPDATE TRIGGER verwenden. Es wird ausgelöst, bevor der Aktualisierungsvorgang ausgeführt wird. In realen Szenarien wird es hauptsächlich für folgende Zwecke verwendet:

  1. Datenvalidierung

  2. Werte automatisch aktualisieren

  3. Datenprotokollierung oder Überwachung

1. Datenvalidierung

Angenommen, einige Unternehmen haben offene Stellen und bereits Bewerbungsdaten. Die Kriterien sind:

  1. Die Berufserfahrung muss mindestens 3 Jahre betragen

  2. Ein vorheriger Bewerbungsversuch darf nicht in den letzten 2 Jahren durchgeführt werden.

Um die Datenintegrität sicherzustellen, erstellen wir den TriggerBEFORE UPDATEund beschränken UPDATE auf Daten, die gegen eines der oben genannten Kriterien verstoßen.

1.1 First, we will create table job_openings.

Stellenangebote

--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;

APPLICATION_ID

VORNAME

NACHNAME

BERUFSERFAHRUNG

LAST_APPLIED_DATE

1

Mark

Sharma

10

01. Januar 2012

2

Praveen

Kumar

4

01. DEZ-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. Werte aktualisieren

EinBEFORE UPDATE löst ein Beispiel aus, um:NEW.UPDATED_BY und:NEW.UPDATED_DATE automatisch zu aktualisieren.

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

VORNAME

NACHNAME

ANSTELLUNGSDATUM

AKTUALISIERT VON

NEUES DATUM

101

Teufel

Khedut

06-JUN-2017

null

null

102

Kanji

Yadav

06-JUN-2017

null

null

2.4 Update records and it will fires the before update trigger. Die Werte vonUPDATED_BY undUPDATED_DATE werden automatisch aktualisiert.

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

VORNAME

NACHNAME

ANSTELLUNGSDATUM

AKTUALISIERT VON

NEUES DATUM

101

Lavji

Khedut

06-JUN-2017

HR

06-JUN-2017

102

Jogi

Yadav

06-JUN-2017

HR

06-JUN-2017

3. Logging/Auditing data

In diesem Beispiel haben wir einen Trigger erstellt, der vor jeder Aktualisierung der Transaktionstabelle Zeilen in eine Prüftabelle einfügt. Immer wenn Benutzer UPDATE-Daten vonbank_transactions verwenden, werden die alten Daten per Trigger für Prüfungs- oder Sicherungszwecke inbank_transactions_audit eingefügt.

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

PARTEINAMEN

TXN_DATE

ERSTELLT VON

CREATED_DATE

1

TXN1234

Peter Thomas

12. MAI 2017

HR

06-JUN-2017

2

TXN9999

Jemes Patel

10. Juni 2016

HR

06-JUN-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

PARTEINAMEN

TXN_DATE

ERSTELLT VON

CREATED_DATE

1

NEWTXN8080

Peter Thomas

12. MAI 2017

HR

06-JUN-2017

2

NEWTXN9595

Jemes Patel

10. Juni 2016

HR

06-JUN-2017

select * from BANK_TRANSACTIONS_AUDIT;

TXN_ID

TXN_NUMBER

PARTEINAMEN

TXN_DATE

ERSTELLT VON

CREATED_DATE

1

TXN1234

Peter Thomas

12. MAI 2017

HR

06-JUN-2017

2

TXN9999

Jemes Patel

10. Juni 2016

HR

06-JUN-2017