Oracle 中的有效日期检查

问题描述 投票:0回答:7

我有一个以 varchar 格式存储的日期值(有效日期或无效日期)。是否可以在sql查询中检查日期是否有效。

oracle date
7个回答
10
投票

是的,如果你知道格式并且很少使用 plsql。

假设您的日期格式为

'yyyy-mon-dd hh24:mi:ss'

create function test_date(d varchar2) return varchar2
is
  v_date date;
begin
  select to_date(d,'yyyy-mon-dd hh24:mi:ss') into v_date from dual;
  return 'Valid';
  exception when others then return 'Invalid';
end;

现在您可以:

select your_date_col, test_date(your_date_col)
from your_table;

4
投票

你可以像这样在一个块中完成它

BEGIN select TO_DATE(your_date,'YYYYMMDD') from dual; --ADD INTO V_DUMMY IN PLSQL EXCEPTION WHEN OTHERS THEN dbms_output.put_line('NOT A VALID DATE'); END;
    

3
投票
无需使用块或创建自定义函数或过程,您可以仅使用下面的 select 语句,以便它返回从日期字符串解析的真实日期值,如果无法识别日期字符串则返回 null。

这种方法有局限性。请参阅下面的注释。

select case when regexp_substr(DateStr,'^[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{4}$') is not null then case when to_number(regexp_substr(DateStr,'[^-]+',1,1))<=12 and to_number(regexp_substr(DateStr,'[^-]+',1,2))<=31 then add_months(to_date('01-01-1900','MM-DD-YYYY'),(to_number(regexp_substr(DateStr,'[^-]+',1,3))-1900)*12+to_number(regexp_substr(DateStr,'[^-]+',1,1))-1)+to_number(regexp_substr(DateStr,'[^-]+',1,2))-1 else null end else null end RealDateVal from MyTable

此示例采用日期格式为“MM-DD-YYYY”,并假设“MyTable”具有日期字符串列“DateStr”。您可能需要根据需要进行相应调整。

总体方法是首先检查日期字符串的格式为??-??-????哪里有一个“?”是一个数字,然后检查第一个??不大于 12(月份),第二个 ??不大于 31(针对日期)。如果全部通过,则通过使用“add_months()”函数构建年份和月份,并使用“+”函数构建日期来组装日期类型的值。如果不满足这些条件中的任何一个,则返回 null。

注 1:由于我们没有简单的方法来检查一年是否有 2 月至 29 日,而且我懒于检查一个月是否有 31 日,因此一天呈现为无效的 29 日、30 日或 31 日,这不会是通过有效性检查,将推迟到下个月。 (请参阅下面的示例。)并且查询永远不会返回错误。

注2:“case when ... is not null then ... else ... end”是惰性的,因此它不会评估“then ...”部分以潜在地触发错误,在这种情况下如果“当...不为空”不满足。此功能是整个方法的基础。相反,函数 nvl2() 不是惰性函数,不能用来代替。

示例 '06-15-2015' -> 返回有效日期
'06-15-2015 ' -> 返回 null
'06/15/2015' -> 返回 null
'15-06-2015' -> 返回 null
'06-31-2015' -> 返回有效日期为 07-01-2015
'02-30-2015' -> 返回有效日期为 03-02-2015

更进一步: 根据您想要走多远,您可以通过将解析的日期值转换回字符串并将其与原始日期字符串值进行比较来减轻“注释 1”中显示的限制。


1
投票
只需使用 to_date 函数来检查日期是否有效/无效。

BEGIN select TO_DATE(your_date,DateFormat) from dual; EXCEPTION WHEN OTHERS THEN dbms_output.put_line('NOT A VALID DATE'); END;
    

1
投票
而且这种方法也是一个简单的 select 语句,不使用块、自定义函数或存储过程。

此示例假设日期格式为“MM-DD-YYYY”。它首先验证格式为“??-??-??????”在哪里 ”?”使用正则表达式是一个数字,然后验证月份(第一个“??”)不大于12,然后使用last_day()函数查找给定有效年/月的最后一天,以验证是否日部分(第二个“??”)是该月的有效部分。当全部有效时,则使用to_date()函数进行解析,否则返回null。

select case when regexp_substr(DateStr,'^[[:digit:]]{1,2}-[[:digit:]]{1,2}-[[:digit:]]{4}$') is not null then case when to_number(regexp_substr(DateStr,'[^-]+',1,1))<=12 then case when to_number(regexp_substr(DateStr,'[^-]+',1,2)) <= extract(day from last_day(add_months(to_date('01-01-1900','MM-DD-YYYY'),(to_number(regexp_substr(DateStr,'[^-]+',1,3))-1900)*12+to_number(regexp_substr(DateStr,'[^-]+',1,1))-1))) then to_date(DateStr,'MM-DD-YYYY') else null end else null end else null end InstallDate from MyTable
    

0
投票
FUNCTION IsDate( p_str IN VARCHAR2, p_format IN VARCHAR2 ) RETURN NUMBER AS V_date DATE; BEGIN V_Date := TO_DATE( p_str, p_format ); RETURN 1; EXCEPTION WHEN OTHERS THEN RETURN 0; END;

致电:

select lastlogin, IsDate(lastlogin,'MM/dd/yyyy hh24:mi:ss') from users_table
    

0
投票
也许为时已晚,但我刚刚在

oracle 19 文档中找到了这个优雅的解决方案

select cast('2024-01-07' as DATE DEFAULT '9999-12-31' ON CONVERSION ERROR, 'YYYY-MM-DD') as datum
from dual;
© www.soinside.com 2019 - 2024. All rights reserved.