具有多种日期格式的 Oracle Varchar2 列

Oracle Varchar2 column with multiple date formats

我有一个 table (我的 table )和一个 varchar2 列 (my_column) ,这个列包含可能是日期的数据,几乎所有已知的日期格式。像 dd/mm/yyyy mm/dd/yyyy ddMONyyyy ddmmyyyyy yymmdd mm.dd.yy dd/mm/yyyy hh:24:ss 年月日 等等。 它还可以包含自由文本数据,可以是数字或文本。 我需要尽可能快的方法将它检索为日期,如果它不能匹配任何日期格式来检索 null

据说这是一种糟糕且危险的日期存储方式,您可以尝试以下方式:

select myColumn,
       coalesce(
                to_date(myColumn default null on conversion error, 'dd/mm/yyyy' ),
                to_date(myColumn default null on conversion error, 'yyyy mm dd' ),
                ...                                                 /* all the known formats */
                to_date(myColumn default null on conversion error ) /* dangerous */
                )
from myTable

在这里,我会以正确的顺序列出所有可能的预期格式,并尽量避免 to_date 没有格式掩码,这可能非常危险并会给您带来意想不到的结果。

简单的答案是:您不能将字符串转换为日期。

您说可能的格式包括 'dd/mm/yyyy''mm/dd/yyyy'。那么 '01/02/2000' 是什么日期呢? 2 月 1 日还是 1 月 2 日?你不知道这一点,所以转换是不可能的。

话虽如此,您可能希望编写一个存储过程,您可以在其中自行解析文本并仅转换明确的字符串。

例如:是否有包含冒号的子串?那么这可能是时间部分。在字符串的其余部分:是否有四位数字?那么这可能是一年。依此类推,直到您 100% 确定 date/time 这是什么,或者您无法明确确定日期(在这种情况下,您希望 return 为 null)。

示例:'13/01/21' 看起来很像 2021 年 1 月 13 日。或者您是否允许在 table 或什至 2001 年甚至 1921 年或...中使用 2013 年?如果您知道不能少一年,例如 table 中的 2019 年,并且不能大于 2021 年,那么年份必须是 2021 年。13 不能是月份,所以它必须是日期,它离开01 这个月。如果您不能排除所有其他选项,那么您将不得不 return null.