【问题标题】:Convert a character column with multiple date formats to a date将具有多种日期格式的字符列转换为日期
【发布时间】:2012-12-13 19:13:09
【问题描述】:

我正在尝试使用 varchar 列更新日期列

update tbl set columnA = columnB

这里,columnA 是 varchar 数据类型,columnB 是日期数据类型。 columnA 有多种日期格式,例如 09302012、9/30/2012、2012-09-30 等不同类型

如何编写单个查询以在单个查询中使用各种类型的日期格式更新列。

已编辑:::

抱歉搞砸了..我刚刚意识到这些是 ssis 包中的单个(部分)更新...

我们有不同类型(6)的品牌,并且对于每个品牌,他们发送具有不同日期格式的不同文件

类型 1 包含日期格式,例如 09/22/2011 9/22/2011 和 2012-09-22

其余所有类型都遵循相同的格式..它的 09222012

所以现在我需要为单个类型编写查询...(直接说只有两个逻辑,一个用于类型 1,另一个用于其余所有类型)

第一个查询逻辑包含三种格式的 case 语句,第二个查询逻辑包含其他格式的逻辑...

最终结果应显示为 2012-09-22 00:00:00(即 yyyy-dd-mm hh:mm:ss) 你能帮帮我吗

我是一个 T-sql 人,不知道 pl-sql 的任何内容(如果它在 t-sql 中,我会直接使用转换和子字符串)

【问题讨论】:

  • 您的varchar2 列应采用与to_date 格式掩码一致的特定格式。如果您不知道varchar2 列中的格式是什么,那么确定varchar2 列中每一行的格式可能是无穷无尽的if...else。这就是为什么 varchar2 类型的日期数据是一个坏主意的原因。
  • 根据您的UPDATE 声明,您正在尝试将DATE 分配给VARCHAR2 列。根据您的问题的文本和标题,您正在尝试将 VARCHAR2 分配给 DATE 列。您的 UPDATE 语句是否反转(即您真的将 columnAVARCHAR2 分配给 columnBDATE)?

标签: sql oracle date oracle10g


【解决方案1】:

你没有。

首先,您下次正确执行此操作,并将日期存储在 DATE 数据类型中;如果这是提供的数据,那么您对您的供应商大喊1

清理数据的最简单方法是创建一个函数来测试日期是否为特定格式:

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;

接下来你选择一个format model 并更新那个。

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

然后您必须选择不同的格式模型并重新执行此操作,直到您的日期列中没有任何为 NULL 的记录。

1。大喊大叫可能有点多,但请确保你被听到了。


这可以提炼成一个带有大型 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

【讨论】:

  • 是的,我经常对供应商大喊大叫 :)
  • 抱歉搞砸了..我刚刚意识到这些是 ssis 包中的个别(部分)更新......我们有不同的类型(6)的品牌,并且每个品牌都发送不同的文件类型 1 的不同日期格式包含日期格式,如 09/22/2011 9/22/2011 和 2012-09-22,其余所有类型都遵循相同的格式..它的 09222012
  • 所以现在我需要为单个类型编写查询...(直接说只有两个逻辑一个用于类型 1,另一个用于其余所有类型)第一个查询逻辑包含三种格式的 case 语句第二个查询逻辑包含其他格式的逻辑......最终结果应该显示为 2012-09-22 00:00:00(即 yyyy-dd-mm hh:mm:ss)你能帮我吗? T-sql 的家伙,不知道任何来自 pl-sql 的东西(如果它在 t-sql 中,我会直接使用转换和子字符串)
  • @MtKr,您仍然可以使用我的答案,只需按照说明使用 to_date()
【解决方案2】:

如果我遇到这样的问题,那么我的第一个问题是如何以编程方式检测每行的日期格式 columnA。 假设它在合理的 LOE 内是可行的(我不知道您的日期格式的完整范围),然后我会看看如何使用 CASE 表达式来检测格式,然后为每种情况相应地格式化日期。

【讨论】:

    【解决方案3】:

    如果我理解您的问题,我认为您应该能够在一个语句中更新您的表格。这不是最优雅的解决方案,但以下应该可行。

    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'));
    

    在上面的语句中,我假设您有一个名为 type 的列,它指示 B 列所在的日期格式。上面的语句使用 DECODE 来确定类型是否为 1。由于type 1 有 3 种可能的格式,然后语句将尝试确定 columnB 的格式。为了使我们的工作更容易,我们只需要测试 YYYY-MM-DD 格式,因为我们可以使用 MM/DD/YYYY 格式2011 年 9 月 22 日和 2011 年 9 月 22 日。所以我们使用 INSTR 函数来确定第一个 '-' 字符的位置。如果该位置是 5,那么我们知道该列是 YYYY-MM-DD 格式并且可以使用适当的日期掩码。如果位置不是 5,那么我们知道 columnB 是 MM/DD/YYYY 格式。最后,如果类型不是 1,那么我们知道日期掩码应该是 MMDDYYYY

    【讨论】:

      猜你喜欢
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 2021-03-07
      • 2013-12-28
      • 1970-01-01
      相关资源
      最近更新 更多