Oracle Update Statement:有效日期检查有问题

时间:2014-08-11 22:28:11

标签: sql oracle sql-update

因此,我正在努力修复一个表格(我们称这个' test')有数千个需要清理数据的条目。我正在修复的表格(我们称之为' textlog')是一个varchar2数据类型。通常,该列以任意数量格式的日期开头,后跟某些类型的描述,如下例所示:

03/01/05-randomtext randomtext
03/01/2005 - randomtext randomtext
03/1/05//randomtext randomtext
03/1/2005 randomtext randomtext
3.01.2005 randomtext randomtext
3.01.05//randomtext randomtext
3-1-05 - randomtext randomtext
3-1-2005 randomtext randomtext
2005/03/01 - randomtext randomtext
2005/3/1//randomtext randomtext
2005.3.01 randomtext randomtext
2005-03-1 randomtext randomtext

所有这些数据都是手动输入的,这就是为什么它在这种格式的噩梦中。但是,如上所示,将月份,日期和年份分开的唯一字符是&#39; /&#39;,&#39; - &#39;或&#39;。&#39; < / p>

我需要做的是更改此列中的所有数据,以便如果它以日期开头,则更改为格式RRRR / MM / DD,然后是文本字符串(仍包含在同一列中) )。因此,当我通过它时,上面的数据需要看起来像这样:

2005/03/01 randomtext randomtext

有些列首先以文本开头,但所有这些都可以忽略。我只关心以日期开头的条目。我遇到的问题有时是某人犯了输入数据并输入无效日期(例如1月0日)的错误,我的查询就在那里停止了。我无法确定有多少无效日期或它们究竟是哪些条目,所以最好也忽略这些日期。

以下是遇到无效日期时遇到问题的当前查询。由于我确信您能够从我的代码中说出来,我对SQL很陌生,所以我很感激您提供的任何帮助,无论是否使用我当前的代码都建议一种完全不同的方法。

注意 - 代码的设置方式是为了涵盖所有当前格式的日期(在我的例子中如上所述)

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 10), to_char(to_date(substr(logtext, 1, 10), 'MM/DD/RRRR'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 9), to_char(to_date(substr(logtext, 1, 9), 'MM/DD/RRRR'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9]/[0-9]/[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]-[0-9]-[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]\.[0-9]\.[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 8), to_char(to_date(substr(logtext, 1, 8), 'MM/DD/RRRR'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]/[0-9]/[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]-[0-9][0-9]-[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]-[0-9]-[0-9][0-9][0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]\.[0-9]\.[0-9][0-9][0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 7), to_char(to_date(substr(logtext, 1, 7), 'MM/DD/RRRR'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9]/[0-9]/[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]/[0-9][0-9]/[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]-[0-9]-[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]-[0-9][0-9]-[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9]\.[0-9]\.[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]\.[0-9][0-9]\.[0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 6), to_char(to_date(substr(logtext, 1, 6), 'MM/DD/RRRR'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9]/[0-9]/[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]-[0-9]-[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9]\.[0-9]\.[0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 10), to_char(to_date(substr(logtext, 1, 10), 'RRRR/MM/DD'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 9), to_char(to_date(substr(logtext, 1, 9), 'RRRR/MM/DD'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]/[0-9]/[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]-[0-9]-[0-9][0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]\.[0-9][0-9]\.[0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]\.[0-9]\.[0-9][0-9][^0-9]');

update test
set logtext = REPLACE(logtext, substr(logtext, 1, 8), to_char(to_date(substr(logtext, 1, 8), 'RRRR/MM/DD'), 'RRRR/MM/DD'))
    where regexp_like(logtext, '^[0-9][0-9][0-9][0-9]/[0-9]/[0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]-[0-9]-[0-9][^0-9]')
    or    regexp_like(logtext, '^[0-9][0-9][0-9][0-9]\.[0-9]\.[0-9][^0-9]');

谢谢!

1 个答案:

答案 0 :(得分:0)

Create table T_53337_tmp (unparsed varchar(100)); --input



insert into T_53337_tmp values('03/01/05-randomtext randomtext');
insert into T_53337_tmp values('03/01/2005 - randomtext randomtext');
insert into T_53337_tmp values('03/1/05//randomtext randomtext');
insert into T_53337_tmp values('03/1/2005 randomtext randomtext');
insert into T_53337_tmp values('3.01.2005 randomtext randomtext');
insert into T_53337_tmp values('3.01.05//randomtext randomtext');
insert into T_53337_tmp values('3-1-05 - randomtext randomtext');
insert into T_53337_tmp values('3-1-2005 randomtext randomtext');
insert into T_53337_tmp values('2005/03/01 - randomtext randomtext');
insert into T_53337_tmp values('2005/3/1//randomtext randomtext');
insert into T_53337_tmp values('2005.3.01 randomtext randomtext');
insert into T_53337_tmp values('2005-03-1 randomtext randomtext');


Update T_53337_tmp  set unparsed= REGEXP_REPLACE(unparsed,
                        '^([0-9]+)([. /-]+)([0-9]+)([. /-]+)([0-9]+)([. /-]+)(.*)$'
                          ,'\1-\3-\5');

在此阶段您有以下数据

03-01-05        
03-01-2005  
03-1-05     
03-1-2005   
3-01-2005   
3-01-05     
3-1-05      
3-1-2005    
2005-03-01  
2005-3-1    
2005-3-01   
2005-03-1

此处另一个重要的事情是您可能会解析不正确的值。如果你得到02-01-12,可能是2012年1月2日或2012年2月1日,甚至是2002年1月12日。

在您弄清楚如何解决上述逻辑问题之后: 使用自定义函数检查日期的有效性。

(来自https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:890580198758

CREATE OR REPLACE FUNCTION MY2DATE (p_str IN VARCHAR2
  ,format_picture IN VARCHAR2
)
   RETURN DATE
IS
BEGIN
   RETURN TO_DATE(p_str, format_picture);
EXCEPTION
   WHEN OTHERS
   THEN
      RETURN NULL;
END;
/

您的最终更新声明将是(仅来自输入的一个案例DD-MM-YYYY的示例如下;您可能需要为您认为从上面有效的每种格式分别写一个更新。)(SQL NOT TESTED)< / p>

Update T_53337_tmp  
set unparsed= 
to_char(MY2DATE(unparsed,'DD-MM-YYYY'),'YYYY/MM/DD') 
where MY2DATE(unparsed,'DD-MM-YYYY') is not null;

(假设您需要的最终统一格式为&#39; YYYY / MM / DD&#39;)