【问题标题】:How to update dates stored as varying character formats (PL/SQL)?如何更新存储为不同字符格式(PL/SQL)的日期?
【发布时间】:2009-06-04 12:44:50
【问题描述】:

问题:我有一个大型数据库表(约 50 万条记录),其中包含存储在 varchar2(15) 列中的日期列表。这些日期以不同的格式存储,即。有些是 yyyy-mm-dd,有些是 mm/dd/yyyy,有些是 dd/mm/yy,有些是 mm/dd/yy,等等。即:

1994-01-13
01/13/1994
01/13/94
13/01/94
13/01/1994
etc

我需要能够稍微改变这些日期,例如为每个日期添加 30 天。 (这是对我的目标的过度简化,但这样更容易解释)。

如果所有日期的格式一致,我将按如下方式实现:

UPDATE history_table
    SET some_date_col = 
        to_char(to_date(some_date_col, 'mm/dd/yyyy')+30, 'mm/dd/yyyy') 
    WHERE some_date_col IS NOT NULL;

由于数据库的大小,我无法逐个循环遍历这些值并解析日期值。任何人都可以提出一种不使用循环(即使用大量 UPDATE 语句)来完成此任务的方法吗?

【问题讨论】:

  • PS 我可以忍受不知道 2009 年 1 月 2 日是指 2009 年 1 月 2 日还是 2009 年 2 月 1 日,只要我可以确定地假设它是其中一个并将其转换为那个日期 + 30 天。
  • 如果您的所有数据都来自美国,您可能可以这样做,但如果您输入的是国际数据,那么您无法轻易确定是哪一个。

标签: sql database oracle datetime plsql


【解决方案1】:

这些日期的格式真的那么重要吗?它们应该是日期时间列。然后您可以在该字段上使用日期数学函数。

【讨论】:

  • 我同意你的观点,但是我没有创建数据库,也无法更改它!我必须按原样接受结构。 :(
  • @JJ 你为什么不去改变它?
  • 这与我的问题无关,但是我支持企业应用程序的后端数据库。由于我无法更改应用程序以适应任何数据库架构更改,因此我必须保持数据库结构不变。我只能操作数据,不能操作结构。
  • 您可以添加一个额外的列,或者您可以创建一个与表同名的视图并构建一些而不是触发器。应用程序不必知道。
  • 这是一个简单明了的混乱,如果你可以有 DD/MM/YYYY 和 MM/DD/YYYY,那么你的数据实际上已经损坏了。我可以为此提供的唯一答案是使用日期作为日期 - 永远不要将日期存储为字符串。除了您的问题之外,如果您没有日期作为日期,则无法进行有效的日期范围扫描等。如果我要处理这个烂摊子,我会对每个字符串进行 to_date,在其上使用日期算术函数,然后再次将它们返回 to_char,随时捕获异常。
【解决方案2】:

好吧,你在这里遇到了一个真正的问题。 07/07/1994 适用于 'MM/DD/YYYY' 和 'DD/MM/YYYY' 但是,在该问题之外,您可以尝试嵌套解码。 我在 varchar 字段中输入了以下日期:

2009 年 1 月 12 日、2009 年 1 月 12 日、2009 年 1 月 12 日、2009 年 1 月 12 日

并使用以下内容,我一直在 2009 年 1 月 12 日返回。您必须找出所有可能的模式并继续嵌套解码。您可以做的另一件事是创建一个函数来处理这个问题。在该函数中,您可以更详细地检查日期格式。它也将更容易阅读。正如您所提到的,您可以在更新语句中使用该函数,这样它应该比循环更快。 (对于它的价值,像这样循环遍历 500k 行应该不会花费很长时间。我经常需要逐行更新 1200 万条记录的表)

选择我的日期, decode(instr(mydate,'-'),5,to_date(mydate,'YYYY-MM-DD'),3,to_date(mydate,'MM-DD-YYYY'), 解码 (长度(mydate),8,to_date(mydate,'MM/DD/YY'),10,to_date(mydate,'MM/DD/YYYY'))) 来自我的约会;

这里是更新声明:

update mydates set revdate = decode(instr(mydate,'-'),5,to_date(mydate,'YYYY-MM-DD'),3,to_date(mydate,'MM-DD-YYYY'), decode (length(mydate),8,to_date(mydate,'MM/DD/YY'),10,to_date(mydate,'MM/DD/YYYY')))

【讨论】:

  • 这对我来说似乎是最好的选择,我会试一试,谢谢!
  • 祝你好运。需要帮助请叫我。我花了好几年的时间在这样的垃圾上进行数据转换。
【解决方案3】:

恕我直言,你有一个更大的问题:

如果有些日期是 dd/mm/yyyy,有些是 mm/dd/yyyy,您如何区分适用于特定日期的格式?

例如,我如何知道值“12/09/2008”是指 12 月还是 9 月?

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多