Sql Oracle更新语句:有效日期检查有问题

Sql Oracle更新语句:有效日期检查有问题,sql,oracle,sql-update,Sql,Oracle,Sql Update,因此,我正在修复一个表,我们称之为“测试”,其中包含数千个需要清理数据的条目。我正在修复的表中我们称之为“textlog”的列当前是一个varchar2数据类型。通常,该列以任意格式的日期开头,后跟某种类型的描述,如以下示例所示: 03/01/05-randomtext randomtext 03/01/2005 - randomtext randomtext 03/1/05//randomtext randomtext 03/1/2005 randomtext randomtext 3.01.

因此,我正在修复一个表,我们称之为“测试”,其中包含数千个需要清理数据的条目。我正在修复的表中我们称之为“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
所有这些数据都是手工输入的,这就是为什么它是一种梦魇般的格式。但是,如上所示,分隔月、日和年的唯一字符是“/”、“-”或“.”

我需要做的是更改此列中的所有数据,这样,如果它以日期开头,它将更改为格式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]');
谢谢

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
这里另一个重要的事情是,您可能解析不正确的值。如果你得到2012年1月2日,可能是2012年1月2日或2012年2月1日,甚至是2002年1月12日

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

您的最终更新语句将仅作为以下输入中DD-MM-YYYY的一种情况的示例;您可能需要为上面确定的每个有效格式编写一个更新。SQL未测试

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;

假设您需要的最终统一格式是“YYYY/MM/DD”

我想我不太明白您的意思。再一次,我是SQL的新手,所以我需要在整个过程中保持我的手,哈哈。我想我没有提到我正在使用Oracle,但我猜这是通过标题中提到的PL/SQL所暗示的。我已经使用“CREATETABLEAS”语句复制了该表,以检查我的查询是否有效。您的意思是一次只将少量数据加载到该表中,然后进行更新吗?我不懂如何使用ISDATE部件。对不起,我希望我能更好地理解:ISDATE是ms sql server的。Oracle没有等效函数,因此需要使用新的自定义函数。按照上面的思路尝试,我已经测试了初始regexp,但没有测试自定义函数。请让我们知道它是否有效。很抱歉回复太晚。我的项目需求发生了变化,我走了一条完全不同的道路。基本上,我改进了我的选择,不得不根据情况将无效日期更改为几个月的最后几天或第一天。如果你对我的改变感兴趣,我可以给你发一个PM,详细说明我的路线。不过谢谢你的帮助,它提供了很多信息,最后我再次使用了你的日期检查功能,很抱歉反应太晚。没问题,把你的答案贴在这里,以便对其他人有用。如果我的回答有帮助的话,也请投赞成票;
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;