Oracle PL/SQL - Пример до УДАЛИТЬ Триггер

Oracle PL / SQL - пример триггера перед DELETE

В этой статье показано, как использоватьBEFORE DELETE TRIGGER, он сработает до выполнения операции удаления. В сценариях реальной жизни он в основном используется для следующих целей:

  1. Ограничить недопустимую операцию DELETE.

  2. Удалить данные из другой таблицы.

1. Ограничить недопустимую операцию DELETE

В этом примере у нас есть две таблицы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

Непоседа Spinner

TOYS

10

2

Радио

ЭЛЕКТРОНИКА

15

3

Игрушки Автомобиль

TOYS

25

4

мобильный

ЭЛЕКТРОНИКА

150

select * from ORDER_DETAILS;
НОМЕР ЗАКАЗА ITEM_ID КОЛИЧЕСТВО ДАТА ЗАКАЗА ПОЛОЖЕНИЕ ДЕЛ

101

1

5

10-ИЮН-2017

ВЫПОЛНЕНО

102

2

2

15-ИЮН-2017

ОТМЕНЕН

103

4

1

17-ИЮН-2017

ОЖИДАНИЕ

104

4

1

01-ИЮН-2017

ВЫПОЛНЕНО

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. УДАЛИТЬ из другой таблицы

В этом примере у нас есть две таблицы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)
);

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 НОМЕР ТЕЛЕФОНА

1

Дьявол Лал

9898989898

2

Мартин Кийосаки

9090909090

select * from PATIENT_DETAILS;
PD_ID PATIENT_ID БОЛЕЗНЬ ADMITTED_DATE ВРАЧ

101

1

ВЫСОКАЯ ТЕМПЕРАТУРА

10-ИЮН-2016

Dr. Р.Дж. Шарма

102

1

COLD

01-ДЕК-2016

Dr. Р.Дж. Шарма

103

2

АРТРИТ

01 декабря 2015 г.

Dr. К.Д. Верма

104

2

БОЛЬ В СПИНЕ

12-ФЕВ-2017

Dr. К.Д. Верма

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

ВЫСОКАЯ ТЕМПЕРАТУРА

10-ИЮН-2016

Dr. Р.Дж. Шарма

102

1

COLD

01-ДЕК-2016

Dr. Р.Дж. Шарма