Oracle Trigger для управления значением order_Status, используемым для работы - PullRequest
0 голосов
/ 12 декабря 2011

РЕДАКТИРОВАТЬ: Пожалуйста, не обращайте внимания, я исправил это, отключив, а затем снова включив триггер.Я не совсем понимаю, почему или как это исправило это, поскольку я никогда не отключал это во-первых.Спасибо всем.

Этот триггер предназначен для управления порядком значений order_status.Поэтому заказ со статусом «Отправлено» не может стать «Готов к отправке», или заказ со значением «Доставлено» не может стать «Отправлен» и т. Д.

Раньше он работал нормально, но сегодня я преобразовалупорядочить таблицу в таблицу объектов (ну, уронить ее, создать тип и т. д.), и с тех пор она не работает.Ограничения работают нормально, только не этот триггер.Он компилируется без проблем, но он никогда не улавливает ошибкуЕсли бы кто-нибудь мог помочь мне здесь, я был бы признателен.

CREATE OR REPLACE TRIGGER Check_Order_Status  
BEFORE INSERT OR UPDATE ON Customer_Order 
for each row

BEGIN 

IF (:new.order_status='Processed' AND :old.order_status='Delivered'
 OR :new.order_status='Processed' AND :old.order_status='Dispatched' 
 OR :new.order_status='Dispatched' AND :old.order_status='Delivered' 
 OR :new.order_status='Delayed' AND :old.order_status='Delivered' 
 OR  :new.order_status='Ready for Dispatch' AND :old.order_status='Dispatched' 
 OR :new.order_status='Ready for Dispatch' AND :old.order_status='Delivered' 
 OR :new.order_status='Dispatched' AND :old.order_status IS NULL ) 
then  
 RAISE_APPLICATION_ERROR(-20103, 'There has been an issue with the order update or insert.');
ELSE
 dbms_output.put('Order Status of ' || :old.order_no || ' is now ' || :new.order_status);
END IF;

END; 
. 
run

1 Ответ

0 голосов
/ 12 декабря 2011

Вот минималистичная реализация вашего сценария:

SQL> create or replace type order_rec as object
    (order_no number
     , order_status varchar2(30)
     , input_date date
     , ship_date date )
/
  2    3    4    5    6
Type created.

SQL>
SQL> create table Customer_Order of order_rec
/

  2
Table created.

SQL>

и ваш триггер компилируется. Пока все хорошо.

SQL> CREATE OR REPLACE TRIGGER Check_Order_Status
BEFORE INSERT OR UPDATE ON Customer_Order
for each row

BEGIN

IF (:new.order_status='Processed' AND :old.order_status='Delivered'
 OR :new.order_status='Processed' AND :old.order_status='Dispatched'
 OR :new.order_status='Dispatched' AND :old.order_status='Delivered'
 OR :new.order_status='Delayed' AND :old.order_status='Delivered'
 OR  :new.order_status='Ready for Dispatch' AND :old.order_status='Dispatched'
 OR :new.order_status='Ready for Dispatch' AND :old.order_status='Delivered'
 OR :new.order_status='Dispatched' AND :old.order_status IS NULL )
then
 RAISE_APPLICATION_ERROR(-20103, 'There has been an issue with the order update or insert.');
ELSE
 dbms_output.put('Order Status of ' || :old.order_no || ' is now ' || :new.order_status);
END IF;

END;   2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20
 21  /

Trigger created.

SQL>

Давайте создадим строку:

SQL> set serveroutput on

insert into customer_order values ( order_rec (1, 'New', sysdate, null))
/

SQL> SQL>   2
1 row created.

SQL>

update customer_order
set order_status = 'Dispatched'
where order_no = 1
/
SQL>   2    3    4
1 row updated.

SQL>

Хм, это немного тихо. Давайте ткнем это:

SQL> update customer_order
set order_status = 'Processed'
where order_no = 1
/
  2    3    4  update customer_order
       *
ERROR at line 1:
ORA-20103: There has been an issue with the order update or insert.
ORA-06512: at "APC.CHECK_ORDER_STATUS", line 11
ORA-04088: error during execution of trigger 'APC.CHECK_ORDER_STATUS'


SQL>

Ваш триггер работает, по крайней мере, для меня. Так почему же мы не видим вызовов DBMS_OUTPUT.PUT_LINE ()? Не знаю, но, наверное, это ошибка.


Кстати, вы должны извлечь эту логику из триггера и поместить ее в функцию-член объекта. Объект - это набор данных и набор связанных поведений. Проверка состояния определенно является поведением, поэтому еще более неправильно иметь такой триггер для таблицы объектов, чем для обычной таблицы.

...