简体   繁体   English

将具有多种日期格式的字符列转换为日期

[英]Convert a character column with multiple date formats to a date

I'm trying to update a date column with from a varchar column 我正在尝试使用varchar列更新日期列

update tbl set columnA = columnB

Here, columnA is a varchar data type and columnB is a date data type. 这里, columnA是varchar数据类型, columnB是日期数据类型。 columnA has various types of date formats, for instance, 09302012, 9/30/2012, 2012-09-30 and more different types columnA具有各种类型的日期格式,例如,09302012,9 / 30 / 2012,2012-09-30以及更多不同类型

How can I write a single query to update the column with the various types of date formats in single query. 如何在单个查询中编写单个查询以使用各种类型的日期格式更新列。

EDITED::: EDITED :::

sorry about the mess up.. i just Realized that these are individual(pieces) updates in ssis package... 对这个烂摊子感到抱歉..我只是意识到这些是ssis包中的个人(件)更新......

we have diff types(6) of makes and for each make they send different files with different date formats 我们有差异类型(6)的品牌,每个品牌都会发送不同日期格式的不同文件

for type 1 contains date format like 09/22/2011 9/22/2011 and 2012-09-22 类型1包含日期格式,如09/22/2011 9/22/2011和2012-09-22

and the rest all types follows same format..its 09222012 其余所有类型都遵循相同的格式.. 09222012

so now i need to write query for individual types...(straightly speaking only two logics one for type 1 and the other for rest all types) 所以现在我需要为各个类型编写查询...(直接说只有两个逻辑,一个用于类型1,另一个用于休息所有类型)

the first query logic contains a case statement for three formats and the second query logic contain logic for other format... 第一个查询逻辑包含三种格式的case语句,第二个查询逻辑包含其他格式的逻辑...

the end result should show up like 2012-09-22 00:00:00 (ie yyyy-dd-mm hh:mm:ss) can u help me out 最终结果应该显示为2012-09-22 00:00:00(即yyyy-dd-mm hh:mm:ss)你可以帮帮我吗

am a T-sql guy and dont know any thng aby pl-sql(if its in t-sql i would directly do i with convert and substring) 我是一个T-sql家伙,不知道任何thy aby pl-sql(如果它在t-sql中我将直接使用convert和substring)

You don't. 你没有。

Firstly you do it properly next time and store dates in a DATE data type; 首先,您下次正确地执行此操作并将日期存储在DATE数据类型中; if this is supplied data then you yell 1 at your suppliers. 如果这是提供的数据,那么您在供应商处大喊1

The simplest way to clean your data would be to create a function that tests if a date is in a certain format: 清理数据的最简单方法是创建一个测试日期是否采用某种格式的函数:

create or replace function is_date ( 
      P_String in varchar2
    , P_Date_Format in varchar2
      ) return number is

   l_date date;

begin

   l_date := to_date(P_String, P_Date_Format);

   return 1;
exception when others then
   return 0;
end;

Next you pick a format model and update just that one. 接下来,您选择一个格式模型并更新该模型

update my_table
   set date_column = to_date(char_column, 'yyyy-mm-dd')
 where is_date(char_column, 'yyyy-mm-dd') = 1

You then have to pick a different format model and do it all over again until you don't have any records in your date column that are NULL. 然后,您必须选择不同的格式模型并重新执行,直到日期列中没有任何NULL记录。

1. Yelling may be a bit much, but make sure you're heard. 大喊大叫可能有点多,但要确保你听到了。


This could be distilled into a single query with a large CASE statement: 这可以通过大型CASE语句提炼为单个查询:

update my_table
   set date_column = case when is_date(char_column, 'yyyy-mm-dd') = 1
                               then to_date(char_column, 'yyyy-mm-dd')
                          when is_date(char_column, 'yyyymmdd') = 1
                               then to_date(char_column, 'yyyymmdd')
                          ...
                          snip
                          ...
                     end

If I had a problem like this then my first question would be how to programatically detect what date format columnA is for each row. 如果我有这样的问题,那么我的第一个问题是如何以编程方式检测每行的日期格式columnA。 Assuming that it's doable within a reasoanble LOE (I don't know the complete spectrum of your date formats) I'd then see how I could use the CASE expression to detect the format and then format the date accordingly for each case. 假设它在一个可重复的LOE中是可行的(我不知道你的日期格式的完整范围)我会看到我如何使用CASE表达式来检测格式,然后相应地为每个案例格式化日期。

If I understand your question I think you should be able to update your table in one statement. 如果我理解你的问题,我认为你应该能够在一个声明中更新你的表格。 It's not the most elegant solution, but the following should work. 这不是最优雅的解决方案,但以下应该可行。

UPDATE tbl
   SET columnA = DECODE(type, '1', DECODE(INSTR(columnB, '-'), 5, TO_DATE(columnB, 'YYYY-MM-DD'),
                                                                  TO_DATE(columnB, 'MM/DD/YYYY')),
                                   TO_DATE(columnB, 'MMDDYYYY'));

In the above statement I'm assuming you have a column named type that indicates which date format column B is in. The above statement uses the DECODE to determine if the type is 1. Since the type 1 has 3 possible formats , the statement will then try to determine which format columnB is in. To make our job easier we only need to test for the YYYY-MM-DD format as we can use the MM/DD/YYYY format with both 09/22/2011 and 9/22/2011. 在上面的语句中,我假设你有一个名为type的列,它指示列B的日期格式。上面的语句使用DECODE来确定类型是否为1.由于类型1有3种可能的格式,语句将然后尝试确定columnB所处的格式。为了使我们的工作更轻松,我们只需要测试YYYY-MM-DD格式,因为我们可以在09/22/2011和9/22使用MM / DD / YYYY格式/ 2011。 So we use the INSTR function to determine the location of the first '-' character. 所以我们使用INSTR函数来确定第一个' - '字符的位置。 If that position is 5, then we know the column is in the YYYY-MM-DD format and can use the appropriate date mask. 如果该位置为5,那么我们知道该列是YYYY-MM-DD格式并且可以使用适当的日期掩码。 If the position is not 5, then we know columnB is in the MM/DD/YYYY format. 如果位置不是5,那么我们知道columnB是MM / DD / YYYY格式。 Lastly, if the type isn't 1, then we know the date mask should be MMDDYYYY . 最后,如果类型不是1,那么我们知道日期掩码应该是MMDDYYYY

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM