2011-12-11 5 views
0

편집 : 제발 무시, 그것을 해제하고 다시 트리거를 사용하여 고정. 나는 왜 그것을 어떻게 고정 시켰는지 결코 모른다. 모두에게 감사드립니다.

이 트리거는 order_status 값의 순서를 제어하기위한 것입니다. 그래서 "Dispatched"상태의 주문은 "Dispatch Ready"가 될 수 없으며, "Delivered"값을 가진 주문은 "Dispatched"이 될 수 없습니다.오라클 트리거 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 
+0

트리거가 전혀 실행되지 않습니까? –

+0

나는 그렇게 생각하지 않는다. 나는 결코 보여주지 않는 DBMS 출력을 넣으려고 시도했다 (나는 서버 출력을 켜 놓았다). 확실하게 말할 다른 방법이 있습니까? –

답변

0

여기에 시나리오의 최소한의 구현 :

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() 호출을 보지 못합니까? 모르겠지만 아마도 버그 일 것입니다.


덧붙여 트리거에서 논리를 추출하여 개체의 멤버 함수에 넣어야합니다. 객체는 일련의 데이터 및 관련 동작 세트입니다. 상태 유효성 검증은 분명히 동작이므로, 일반 테이블보다 객체 테이블에 트리거를 갖는 것이 훨씬 더 바람직합니다.

관련 문제