2017-05-09 75 views
0

我有一個觸發器在信用卡到期日過期時引發異常。無論我插入什麼日期,都會引發異常。有誰知道爲什麼會發生這種情況?無論條件如何,觸發器總是觸發

觸發:

create or replace trigger card_expired 
before insert or update on invoice 
for each row 
begin 
    if :new.exp_date >= sysdate 
    then 
    raise_application_error(-20000,'Card is expired'); 
    end if; 
end; 

插入語句(EXP_DATE是19年12月31日):

insert into invoice(invoice_id, invoice_date, invoice_due, cc_type, cc_no, 
exp_date, guest_id, reservation_id, admins_id) 
values(invoice_sequence.nextval, sysdate, bill_due(100101), 'Visa', 
'4838892900203328', to_date('12-31-2019','mm/dd/yyyy'), 110, 100101, 110); 
+0

您的插入中沒有列列表。所以我們不知道你在哪裏插入代碼並且你的代碼引入了錯誤。始終使用插入列表。如果你添加一個,你可能會發現你的意外行爲消失 –

+2

你的一年也沒有一個世紀。 19 = 1919年還是2019年?如果你的代碼沒有歧義,你現在或將來都不太可能有錯誤或意外的行爲。 –

+4

2019-12-31肯定比SYSDATE大,所以你的觸發器正在工作。 –

回答

0

假設:exp_date是在INSERT語句中第6個參數。

to_date中的給定格式實際上與給定日期不匹配。

請檢查:

select to_char(to_date('12-31-19','mm/dd/yyyy'), 'mm-dd-yyyy') from dual; 

它提供:

12-31-0019 

因此,它總是比SYSDATE少。

這應該解決您的問題:

to_date('12-31-19','mm-dd-yy') 

甚至更​​好(不約世紀迷惑):

to_date('12-31-2019','mm-dd-yyyy') 
+0

如果你跳過世紀,你應該使用'to_date('12 -31-19','mm-dd-rr')' –

+1

@WernfriedDomscheit - 如果我們使用'yy',Oracle默認爲當前世紀。在這種情況下,這比'rr'更可能是正確的。但最好的解決方案是始終使用明確的四位數年份。 – APC

+0

感謝您的意見。對於格式'yy'和'rr'之間的區別感到困惑的人:[RR日期時間格式元素](http://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements004.htm#SQLRF00215 )。但是,正如@APC所說。我更喜歡總是使用明確的四位數年份。 – kpater87

2

你的檢查是錯誤的,而不是>=應該<=

:new.exp_date >= sysdate