我正在编写简单的SELECT
查询,其中涉及从字符串中解析出日期
用户在Web应用程序中手动输入日期,并在数据库中记录为字符串。
我正在使用CASE
语句来处理各种日期格式,并在TO_DATE
函数中相应地使用正确的格式说明符。
但是,有时,用户错误地输入了不是有效日期(例如13-31-2013)的内容,然后整个查询失败。有没有办法处理这样的rougue记录,并用查询中的一些默认日期替换它们,以便整个查询不会因单个无效的日期记录而失败?
我已经尝试过正则表达式,但在处理闰年和AFAIK月份的30/31天时,它们并不十分可靠。
我没有权限存储过程或类似的东西。它只是简单的SELECT
查询从我的应用程序执行。
答案 0 :(得分:0)
这是一个客户端任务.. 数据库将为无效日期提供错误(数据库没有" TO_DATE_AND_FIX_IF_NOT_CORRECT"函数)。
如果您收到此错误,则表示您已尝试将某些内容投放到无效日期。
我建议您在应用程序服务器上进行日期迁移,如果代码出现异常,请向DB发送默认日期。
另外,通过这种方式,您可以向DB发送类型为DbDate但不是字符串的对象。
这样你实现了两个目标:
1.日期永远是你想要的(来自客户)
你关闭了SQL注入攻击的大门。
听起来在你的情况下你应该写我提到的功能......
Create or replace function TO_DATE_SPECIAL(in_date in varchar2) return DATE is
ret_val date;
begin
ret_val := to_date(in_date,'MM-DD-YYYY');
return ret_val;
exception
when others then
return to_date('01-01-2000','MM-DD-YYYY');
end;
在查询中 - 而不是使用" to_date"使用新功能。
这样而不是失败 - 它会给你一个默认日期。
- >没有IsDate函数..所以你必须为它创建一个对象......
我希望你有这个想法以及如何使用它,如果没有 - 让我知道。
答案 1 :(得分:0)
我最终使用疯狂的正则表达式来检查闰年,30/31天。 这是:
((^(0?[13578]|1[02])[\/.-]?(0?[1-9]|[12][0-9]|3[01])[\/.-]?(18|19|20){0,1}[0-9]{2}$)|(^(0?[469]|11)[\/.-]?(0?[1-9]|[12][0-9]|30)[\/.-]?(18|19|20){0,1}[0-9]{2}$)|(^([0]?2)[\/.-]?(0?[1-9]|1[0-9]|2[0-8])[\/.-]?(18|19|20){0,1}[0-9]{2}$)|(^([0]?2)[\/.-]?29[\/.-]?(((18|19|20){0,1}(04|08|[2468][048]|[13579][26]))|2000|00)$))
这是McKay here答案的修改版本 不是最有效但它的工作原理。我等着看是否有更好的选择。