Oracle PL / SQL - Exemple de déclenchement avant DELETE
Cet article vous montre comment utiliserBEFORE DELETE TRIGGER
, il se déclenchera avant que l'opération de suppression ne soit exécutée. Dans les scénarios de la vie réelle, il est principalement utilisé à des fins telles que:
-
Restreindre l'opération DELETE non valide.
-
Supprimer les données d'une autre table.
1. Restreindre l'opération DELETE non valide
Dans cet exemple, nous avons deux tablesitem_details
etorder_details
. La tableorder_details
contient les valeurs des bons de commande d'articles de la tableitem_details
. Désormais, chaque fois que l'utilisateur souhaite supprimer un article de item_details, nous devons vérifier si une commande EN ATTENTE existe pour cet article ou non.
Si une commande EN ATTENTE est trouvée, nous n'autoriserons pas la suppression de l'élément et augmenterons l'erreur d'application deBEFORE DELETE TRIGGER
pour limiter l'opération de suppression suritem_details
1.1 Create tables and trigger.
DÉTAILS DE L'ARTICLE
CREATE TABLE ITEM_DETAILS ( ITEM_ID number(10) primary key, ITEM_NAME varchar2(30), TYPE varchar2(50), PRICE_IN_DOLLAR number(10) );
DÉTAILS DE LA COMMANDE
CREATE TABLE ORDER_DETAILS ( ORDER_ID number(10) primary key, ITEM_ID number(10), QUANTITY number(5), ORDER_DATE date, STATUS varchar2(20) );
trg_before_item_delete
CREATE OR REPLACE TRIGGER trg_before_item_delete BEFORE DELETE on item_details FOR EACH ROW DECLARE pending_orders number; BEGIN pending_orders := 0; -- Find pending orders SELECT count(1) INTO pending_orders FROM order_Details WHERE item_id = :OLD.item_id AND STATUS = 'PENDING'; -- Check whether any pending order exists or not IF (pending_orders > 0) THEN RAISE_APPLICATION_ERROR(-20000,pending_orders|| ' pending orders found for this item. First COMPLETE or CANCEL the order and then delete.'); END IF; END;
1.2 Insert data for testing.
INSERT INTO ITEM_DETAILS VALUES (1,'Fidget Spinner','TOYS',10); INSERT INTO ITEM_DETAILS VALUES (2,'Radio','ELECTRONICS',15); INSERT INTO ITEM_DETAILS VALUES (3,'Toys Car','TOYS',25); INSERT INTO ITEM_DETAILS VALUES (4,'Mobile','ELECTRONICS',150); alter session set nls_date_format = 'DD-MON-YYYY'; INSERT INTO ORDER_DETAILS VALUES (101,1,5,'10-JUN-2017','COMPLETED'); INSERT INTO ORDER_DETAILS VALUES (102,2,2,'15-JUN-2017','CANCELLED'); INSERT INTO ORDER_DETAILS VALUES (103,4,1,'17-JUN-2017','PENDING'); INSERT INTO ORDER_DETAILS VALUES (104,4,1,'01-JUN-2017','COMPLETED');
1.3 Display the data.
select * from ITEM_DETAILS;
ID DE L'ARTICLE | NOM DE L'ARTICLE | TYPE | PRICE_IN_DOLLAR |
---|---|---|---|
1 |
Fidget Spinner |
TOYS |
10 |
2 |
Radio |
ÉLECTRONIQUE |
15 |
3 |
Jouets voiture |
TOYS |
25 |
4 |
Mobile |
ÉLECTRONIQUE |
150 |
select * from ORDER_DETAILS;
NUMÉRO DE COMMANDE | ID DE L'ARTICLE | QUANTITÉ | DATE DE COMMANDE | STATUT |
---|---|---|---|---|
101 |
1 |
5 |
10-JUIN-2017 |
TERMINÉ |
102 |
2 |
2 |
15-JUIN-2017 |
ANNULÉ |
103 |
4 |
1 |
17-JUIN-2017 |
EN ATTENTE |
104 |
4 |
1 |
01-JUIN-2017 |
TERMINÉ |
1.4 Delete item which have PENDING orders.
DELETE FROM item_details WHERE item_id = 4; -- output Error report - ORA-20000: 1 pending orders found for this item. First COMPLETE or CANCEL the order and then delete. ORA-06512: at "SYSTEM.TRG_BEFORE_ITEM_DELETE", line 11 ORA-04088: error during execution of trigger 'SYSTEM.TRG_BEFORE_ITEM_DELETE'
2. SUPPRIMER d'une autre table
Dans cet exemple, nous avons deux tablespatient
etpatient_details
. Lepatient
contient des détails de base tandis quepatient_details
contient les valeurs d'un patient telles que la maladie, le nom du médecin, etc.
Désormais, chaque fois que l'utilisateur souhaite supprimer des données depatient
, nous devons supprimer les données depatient_details
, car nous n'en avons plus besoin après la suppression d'un patient. Nous allons donc supprimer ici les données parBEFORE DELETE TRIGGER
sur la table patient.
2.1 Create tables and trigger.
PATIENT
CREATE TABLE PATIENT ( PATIENT_ID number(10) primary key, NAME varchar2(30), PHONE_NO number(12) );
PATIENT_DETAILS
CREATE TABLE PATIENT_DETAILS ( PD_ID number(10) primary key, PATIENT_ID number(10), DISEASE varchar2(50), ADMITTED_DATE date, DOCTOR varchar2(30) );
trg_delete_from_details
CREATE OR REPLACE TRIGGER trg_delete_from_details BEFORE DELETE on patient FOR EACH ROW BEGIN -- Delete from PATIENT_DETAILS also DELETE FROM PATIENT_DETAILS PD WHERE PD.PATIENT_ID = :OLD.PATIENT_ID; END;
2.2 Insert data for testing.
alter session set nls_date_format = 'DD-MON-YYYY'; INSERT INTO PATIENT VALUES(1,'Devil Lal',9898989898); INSERT INTO PATIENT VALUES(2,'Martin Kiyosaki',9090909090); INSERT INTO PATIENT_DETAILS VALUES(101,1,'FEVER','10-JUN-2016','Dr. RJ Sharma'); INSERT INTO PATIENT_DETAILS VALUES(102,1,'COLD','01-DEC-2016','Dr. RJ Sharma'); INSERT INTO PATIENT_DETAILS VALUES(103,2,'ARTHRITIS','01-DEC-2015','Dr. KD Verma'); INSERT INTO PATIENT_DETAILS VALUES(104,2,'BACKPAIN','12-FEB-2017','Dr. KD Verma');
2.3 Display the data.
select * from PATIENT;
PATIENT_ID | NAME | PAS DE TÉLÉPHONE |
---|---|---|
1 |
Diable Lal |
9898989898 |
2 |
Martin Kiyosaki |
9090909090 |
select * from PATIENT_DETAILS;
PD_ID | PATIENT_ID | MALADIE | ADMITTED_DATE | MÉDECIN |
---|---|---|---|---|
101 |
1 |
FIÈVRE |
10-JUIN-2016 |
Dr. RJ Sharma |
102 |
1 |
COLD |
01-DÉC-2016 |
Dr. RJ Sharma |
103 |
2 |
ARTHRITE |
01-DÉC-2015 |
Dr. KD Verma |
104 |
2 |
MAL AU DOS |
12-FÉV-2017 |
Dr. KD Verma |
2.4 Delete items from patient
table. Consultez la tablepatient_detail
, les données associées seront supprimées automatiquement par le déclencheur.
DELETE FROM patient WHERE patient_id = 2; -- output -- 1 row deleted.
select * from PATIENT;
PATIENT_ID | NAME | PAS DE TÉLÉPHONE |
---|---|---|
1 |
Diable Lal |
9898989898 |
select * from PATIENT_DETAILS;
PD_ID | PATIENT_ID | MALADIE | ADMITTED_DATE | MÉDECIN |
---|---|---|---|---|
101 |
1 |
FIÈVRE |
10-JUIN-2016 |
Dr. RJ Sharma |
102 |
1 |
COLD |
01-DÉC-2016 |
Dr. RJ Sharma |