2012-07-19 161 views
-1

我是Oracle和SQL的新手,我試圖創建一個觸發器,其中req_ship_date(子訂單表)不能位於order_date(customer_order表)之前。我創建觸發器:Oracle SQL觸發器

create or replace trigger req_ship_date_error 
before insert on suborder 
for each row 
declare 
placed_date date; 
req_date date; 
begin 
select order_date into placed_date 
from customer_order; 
select req_ship_date into req_date 
from suborder 
where suborder_no = :new.suborder_no; 
if placed_date > req_date then 
raise_application_error(-20002, ('Order ' || :new.suborder_no || ' required shipping date cannot be before order date')); 
end if; 
end; 

但即使是嘗試插入一個很好的發言,我發現了以下錯誤

insert into suborder 
values (8, 2, '10-jul-2012', '12-jul-2012', 'CVS', 2); 

ERROR

Error starting at line 1 in command: 
insert into suborder 
    values (8, 2, '10-jul-2012', '12-jul-2012', 'CVS', 2) 
Error report: 
SQL Error: ORA-01422: exact fetch returns more than requested number of rows 
ORA-06512: at "COMPANY.REQ_SHIP_DATE_ERROR", line 5 
ORA-04088: error during execution of trigger 'COMPANY.REQ_SHIP_DATE_ERROR' 
01422. 00000 - "exact fetch returns more than requested number of rows" 
*Cause: The number specified in exact fetch is less than the rows returned. 
*Action: Rewrite the query or change number of rows requested 

任何想法是什麼原因造成這之後?由於

回答

0
  • 作爲@Shine指出,需要對查詢WHERE條款對CUSTOMER_ORDER
  • 上的一個行級觸發器SUBORDER無法再查詢SUBORDER。如果你這樣做,你最終會得到一個突變的表錯誤。假設SUBORDER_NOSUBORDER的主鍵,但是,您不應該查詢該表。只需使用您手中的:new.req_ship_date值即可。

像這樣的東西應該工作假設的customer_order主鍵是order_noorder_no存在於suborder表。

create or replace trigger req_ship_date_error 
    before insert on suborder 
    for each row 
declare 
    l_placed_date date; 
begin 
    select order_date 
    into l_placed_date 
    from customer_order 
    where order_no = :new.order_no; 
    if l_placed_date > :new.req_ship_date 
    then 
    raise_application_error(
     -20002, 
     'Order ' || :new.suborder_no || ' required shipping date cannot be before order date'); 
    end if; 
end; 
+0

明白了,非常感謝你的幫助! – JProg 2012-07-19 16:41:27

1

缺少其中第一觸發器的SELECT查詢子句

select order_date into placed_date 
    from customer_order; 

威爾返回多行,所以Oracle不知道要選擇之日起哪一個(將其放置裏面placed_date變量)。子句總是需要單個行。

添加where子句以便返回單個結果。

+0

我加了:where order_no =:new.order_no;我得到這個:警告:執行完成,警告 觸發req_ship_date_error編譯。 – JProg 2012-07-19 16:06:45

+0

您必須確定order_no是UNIQUE,以便將來不會給您TOO_MANY_ROWS。至於警告,你應該看到日誌文件,但我不會擔心 – Shine 2012-07-19 17:58:17