检查在varchar2中声明的有效日期

时间:2015-04-14 10:53:43

标签: sql oracle

我的表如下所示,在VARCHAR2中声明:

YMD  
20101010  
20101112  
20100231  
20150101  
20160101  

我必须检查有效日期并过滤sysdate中的有效格式的未来日期。

我编写如下函数来检查有效日期:

create or replace FUNCTION VALIDATE_DATE (p_string in string) return date is  
begin  
    return to_date(p_string, 'YYYYMMDD');  
exception when others then  
    begin  
        return to_date(p_string, 'YYYY-MM-DD');  
    exception when others then  
        begin  
            return to_date(p_string, 'RR-MON-DD');  
        exception when others then  
            return null;  
        end;  
    end;  
end;  

并编写此查询以检查有效日期,并将null替换为无效日期

select ymd, VALIDATE_DATE(ymd) as Valid 
from temp

并检查以后的日期我编写了以下查询,但它抛出了错误

  

ORA-01839

select ymd 
from temp
where validate_date(ymd)='YES'
and to_date(ymd,'yyyymmdd')>sysdate

如果存在,如何检查我表中的未来日期?

1 个答案:

答案 0 :(得分:1)

我宁愿将设计问题修复为永久修复,而不是在解决方法上浪费时间。

首先,从不 DATE 存储为 VARCHAR2 。所有这些开销都归因于您的设计存在缺陷

  

'20100231'

这怎么可能是一个有效的约会?哪个日历在FEBRUARY有31天?

请按照以下步骤操作:

  1. 使用日期数据类型添加新列。
  2. 使用 TO_DATE 更新旧列中包含日期值的新列。
  3. 对新的DATE列执行必需的DATE算法,或者在步骤2本身的UPDATE语句中处理此算法。
  4. 放下旧栏。
  5. 将新列重命名为旧列。
  6. 更新添加演示

    <强>设置

    SQL> CREATE TABLE t
      2      (ymd varchar2(8));
    
    Table created.
    
    SQL>
    SQL> INSERT ALL
      2      INTO t (ymd)
      3           VALUES ('20101112')
      4      --INTO t (ymd)
      5      --     VALUES ('20100231')
      6      INTO t (ymd)
      7           VALUES ('20150101')
      8      INTO t (ymd)
      9           VALUES ('20160101')
     10  SELECT * FROM dual;
    
    3 rows created.
    
    SQL>
    SQL> COMMIT;
    
    Commit complete.
    
    SQL>
    

    添加新列:

    SQL> ALTER TABLE t ADD (dt DATE);
    
    Table altered.
    
    SQL>
    

    进行必要的更新

    SQL> UPDATE t
      2  SET dt =
      3    CASE
      4      WHEN to_date(ymd, 'YYYYMMDD') > SYSDATE
      5      THEN NULL
      6      ELSE to_date(ymd, 'YYYYMMDD')
      7    END;
    
    3 rows updated.
    
    SQL>
    SQL> COMMIT;
    
    Commit complete.
    
    SQL>
    

    让我们检查一下:

    SQL> SELECT * FROM t;
    
    YMD      DT
    -------- ---------
    20101112 12-NOV-10
    20150101 01-JAN-15
    20160101
    
    SQL>
    

    删除旧列:

    SQL> ALTER TABLE t DROP COLUMN ymd;
    
    Table altered.
    
    SQL>
    

    将新列重命名为旧列名称

    SQL> ALTER TABLE t RENAME COLUMN dt TO ymd;
    
    Table altered.
    
    SQL>
    

    您刚刚解决了问题

    SQL> SELECT * FROM t;
    
    YMD
    ---------
    12-NOV-10
    01-JAN-15
    
    
    SQL>