处理Oracle中的无效日期

时间:2014-04-07 21:31:01

标签: regex oracle validation datetime oracle11g

我正在编写简单的SELECT查询,其中涉及从字符串中解析出日期 用户在Web应用程序中手动输入日期,并在数据库中记录为字符串。

我正在使用CASE语句来处理各种日期格式,并在TO_DATE函数中相应地使用正确的格式说明符。

但是,有时,用户错误地输入了不是有效日期(例如13-31-2013)的内容,然后整个查询失败。有没有办法处理这样的rougue记录,并用查询中的一些默认日期替换它们,以便整个查询不会因单个无效的日期记录而失败?

我已经尝试过正则表达式,但在处理闰年和AFAIK月份的30/31天时,它们并不十分可靠。 我没有权限存储过程或类似的东西。它只是简单的SELECT查询从我的应用程序执行。

2 个答案:

答案 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答案的修改版本 不是最有效但它的工作原理。我等着看是否有更好的选择。