2012-03-11 38 views
1

我有兩個tables--在Oracle中創建觸發器,它不會允許與if條件

create table mobile 
(
id int, 
m_name varchar(20), 
purchase_date datetime 
) 


insert into mobile values('1','Samsung corby','12-JAN-12'); 
insert into mobile values('2','Nokia E5','15-MAR-12'); 
insert into mobile values('3','Sony Talk','10-FEB-12'); 



create table location 
(
id int, 
l_name varchar(20) 
) 
insert into location values(1,'London'); 
insert into location values(2,'Washington'); 
insert into location values(3,'Mexico'); 

我想創建一個觸發器,這將確保索尼移動談話是在墨西哥任何插入或更新可以不會在12月份購買。這意味着每當我嘗試在ID爲3的移動表格中插入數據並且在12月份購買日期時,觸發器應該停止它並給出適當的消息。

我對這個代碼是 -

create or replace trigger trg1 
before insert or update 
on mobile 
for each row 
declare 
var1 number(4); 
begin 
select id into var1 from location where l_name='Mexico'; 
    IF (:new.id = var1 and to_char(:new.purchase_date, 'MONTH') = 'DECEMBER') THEN 
     raise_application_error(-20001, 'THIS mobile CAN NOT BE PURCHASED NOW.'); 
    END IF; 
end; 

觸發被創造了,但是當我嘗試使用此代碼 -

insert into mobile values('3','Sony Talk','10-JAN-11'); 

觸發器觸發插入此數據,但給出了一個錯誤 -

ORA-04098: trigger 'OPS$0924769.TRG1' is invalid and failed re-validation 

和我如果代碼也無法正常工作properly--

IF (:new.id = var1 and to_char(:new.purchase_date, 'MONTH') = 'DECEMBER') THEN 
     raise_application_error(-20001, 'THIS mobile CAN NOT BE PURCHASED NOW.'); 
    END IF; 

它沒有檢查id和purchase_date。 我把purchase_date設爲JAN,所以在這種情況下觸發器不應該觸發。 我很困惑。

回答

7
  1. 您的觸發器是在編譯錯誤時創建的。如果在創建觸發器後鍵入show errors,則SQL * Plus將向您顯示語法錯誤。
  2. Oracle沒有DATETIME數據類型。 mobile中的purchase_date列的數據類型將需要爲DATE
  3. 觸發你貼我的系統上編譯和運行沒有錯誤,一旦我糾正錯誤的定義mobile
  4. 當您使用TO_CHARMONTH格式掩碼,結果將是正確的填充空格到最長月份的長度(9個字符)。由於DECEMBER只有8個字符,因此您的條件永遠不會評估爲TRUE。您需要輸出TRIM或使用格式掩碼fmMONTH,該掩碼不會用空格填充輸出。

喜歡的東西

create or replace trigger trg1 
before insert or update 
on mobile 
for each row 
declare 
var1 number(4); 
begin 
select id into var1 from location where l_name='Mexico'; 
    IF (:new.id = var1 and to_char(:new.purchase_date, 'fmMONTH') = 'DECEMBER') THEN 
     raise_application_error(-20001, 'THIS mobile CAN NOT BE PURCHASED NOW.'); 
    END IF; 
end; 

會更可能是你在找什麼。但是這並不能解釋你的觸發器爲什麼會出現編譯錯誤。