代码之家  ›  专栏  ›  技术社区  ›  Himanshu

如何在oracle中检查日期是否有效以及格式是否正确?

  •  0
  • Himanshu  · 技术社区  · 5 年前

    正如您在下面看到的,大多数日期都是相同的,但格式不同,其中一个日期无效。因此,在不插入数据的情况下,如何正确插入表中的任何错误都是一个问题。

         select to_date(dob,'dd/mm/yyyy') from table
    

    enter image description here

    1 回复  |  直到 5 年前
        1
  •  2
  •   Gordon Linoff    5 年前

    一种解决方案是正则表达式:

    select (case when regexp_like(dob, '^[0-9]{1,2}/[0-9]{1,2}/[0-9]{4}$'
                 then to_date(dob, 'dd/mm/yyyy') 
                 when regexp_like(dob, '^[0-9]{4}/[0-9]{2}/[0-9]{2}$'
                 then to_date(dob, 'yyyy/mm/dd') 
                 when regexp_like(dob, '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
                 then to_date(dob, 'yyyy-mm-dd') 
            end)
    from t;
    

    数据建模 问题。您存储了 作为一个字符串,这是根本问题。你无法控制输入,所以你不知道3/7/64是指3月7日还是7月3日。

    输入 .

        2
  •  1
  •   APC    5 年前

    '/' '-'

    一个简单的解决方案是使用一个函数将各种日期格式掩码应用于日期字符串,直到成功为止。这是我们的赢家,我们将其作为日期返回。如果没有一个掩码符合字符串,则返回null。

    function cast_to_date (p_str in varchar2) return date is
      d date;
      masks sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll ('dd-mm-yyyy', 'mm-dd-yyyy', 'yyyy-mm-dd');
    begin  
      for idx in 1..masks.count() loop
        begin
          d := to_date(p_str, masks(idx));
          exit;
        exception
          when others then
            d := null;
        end;
      end loop;  
      return d;
    end;
    

    这个版本应用了三个掩码。考虑一下为数组分配掩码的顺序:如果您认为更多的字符串将日期表示为 年月日 年月日 不管你是在1990年4月10日还是1990年10月4日装货,那么你应该相应地更改订单。

    a demo on db<>fiddle of this approach in action . 请注意,我已经在示例中添加了一些输入行。


    大多数日期相同,但格式不同,其中一个日期无效。

    八个日期中的一个无效,还有三个可能是无效的 年月日 年月日 . 这意味着你只能确定样本中25%的日期是正确的。鉴于这一命中率,你也应该对那些人产生怀疑:当然,它们是约会,但它们是正确的吗?扩展一下,你能相信这个源系统传递给你的任何数据吗?你怎么能确定他们对这一个纵队只是漫不经心,而对其他纵队却很严格?我敢打赌 “名字、姓氏和电话号码” 也充满了不可靠的价值观。

    很有可能你为了问题的目的夸大了发布样本中坏日期的数量。但是如果这个分解代表了你得到的数据,那么你应该讨论一下是否值得你花时间加载这些数据,如果你加载了它,你应该在多大程度上信任它进行下游处理。