Oracle PL/SQL - DELETEトリガの例

Oracle PL / SQL-DELETEトリガーの前の例

この記事では、BEFORE DELETE TRIGGERの使用方法を説明します。削除操作が実行される前に起動します。 現実のシナリオでは、主に次のような目的で使用されます。

  1. 無効なDELETE操作を制限します。

  2. 別のテーブルからデータを削除します。

1. 無効なDELETE操作を制限する

この例では、2つのテーブルitem_detailsorder_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つのテーブルpatientpatient_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シャルマ