Oracle PL / SQL-DELETEトリガーの前の例
この記事では、BEFORE DELETE TRIGGER
の使用方法を説明します。削除操作が実行される前に起動します。 現実のシナリオでは、主に次のような目的で使用されます。
-
無効なDELETE操作を制限します。
-
別のテーブルからデータを削除します。
1. 無効なDELETE操作を制限する
この例では、2つのテーブルitem_details
とorder_details
があります。 テーブルorder_details
には、item_details
テーブルのアイテムの発注書の値が含まれています。 これで、ユーザーがitem_detailsからアイテムを削除するたびに、そのアイテムに保留中の注文が存在するかどうかを確認する必要があります。
保留中の注文が見つかった場合、アイテムの削除は許可されず、BEFORE DELETE TRIGGER
からのアプリケーションエラーが発生して、item_details
での削除操作が制限されます。
1.1 Create tables and trigger.
ITEM_DETAILS
CREATE TABLE ITEM_DETAILS ( ITEM_ID number(10) primary key, ITEM_NAME varchar2(30), TYPE varchar2(50), PRICE_IN_DOLLAR number(10) );
注文詳細
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;
ITEM_ID | 項目名 | TYPE | PRICE_IN_DOLLAR |
---|---|---|---|
1 |
フィジェットスピナー |
TOYS |
10 |
2 |
無線 |
エレクトロニクス |
15 |
3 |
おもちゃの車 |
TOYS |
25 |
4 |
モバイル |
エレクトロニクス |
150 |
select * from ORDER_DETAILS;
ORDER_ID | ITEM_ID | 量 | 注文日 | 状態 |
---|---|---|---|---|
101 |
1 |
5 |
2017年6月10日 |
完了しました |
102 |
2 |
2 |
2017年6月15日 |
キャンセル |
103 |
4 |
1 |
2017年6月17日 |
保留中 |
104 |
4 |
1 |
2017年6月1日 |
完了しました |
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. 別のテーブルから削除
この例では、2つのテーブルpatient
とpatient_details
があります。 patient
には基本的な詳細が含まれ、patient_details
には病気や医師名などの患者の値が含まれます。
これで、ユーザーがpatient
からデータを削除する場合は常に、patient_details
からデータを削除する必要があります。これは、患者が削除された後はデータが不要になるためです。 したがって、ここでは、患者テーブルのデータをBEFORE DELETE TRIGGER
だけ削除します。
2.1 Create tables and trigger.
患者
CREATE TABLE PATIENT ( PATIENT_ID number(10) primary key, NAME varchar2(30), PHONE_NO number(12) );
患者の詳細
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 | 電話番号 |
---|---|---|
1 |
デビルラル |
9898989898 |
2 |
マーティン清崎 |
9090909090 |
select * from PATIENT_DETAILS;
PD_ID | PATIENT_ID | 疾患 | ADMITTED_DATE | 医師 |
---|---|---|---|---|
101 |
1 |
熱 |
2016年6月10日 |
Dr. RJシャルマ |
102 |
1 |
COLD |
2016年12月1日 |
Dr. RJシャルマ |
103 |
2 |
関節炎 |
2015年12月1日 |
Dr. KDバーマ |
104 |
2 |
背中の痛み |
2017年2月12日 |
Dr. KDバーマ |
2.4 Delete items from patient
table. patient_detail
テーブルを確認すると、関連データがトリガーによって自動的に削除されます。
DELETE FROM patient WHERE patient_id = 2; -- output -- 1 row deleted.
select * from PATIENT;
PATIENT_ID | NAME | 電話番号 |
---|---|---|
1 |
デビルラル |
9898989898 |
select * from PATIENT_DETAILS;
PD_ID | PATIENT_ID | 疾患 | ADMITTED_DATE | 医師 |
---|---|---|---|---|
101 |
1 |
熱 |
2016年6月10日 |
Dr. RJシャルマ |
102 |
1 |
COLD |
2016年12月1日 |
Dr. RJシャルマ |