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