【问题标题】:Oracle - SQL Query works fine in SQL Developer but throws error ORA - 01861 Literal does not match the format string in SSISOracle - SQL 查询在 SQL Developer 中工作正常,但抛出错误 ORA - 01861 文字与 SSIS 中的格式字符串不匹配
【发布时间】:2021-07-22 10:27:54
【问题描述】:

我正在尝试在 oracle 中将 DD-MON-RR 转换为 YYYY-MM-DD 格式 我已经编写了以下转换,它在 SQL Developer 中运行良好。

TO_CHAR(TO_DATE(日期,'DD-MON-RR'),'YYYY-MM-DD')

但是,如果我在 SSIS 中使用相同的查询,它会抛出 ORA-01861 Literal does not match the format string。

感谢任何帮助!

【问题讨论】:

  • 如果date 部分已经是一个日期,那么不要为此调用to_date();就做TO_CHAR(date,'YYYY-MM-DD')。 See this answer 解释一下。
  • 嗨@AlexPoole,实际问题是我有一个日期列,其值为58 年10 月1 日。这是一个出生日期列,表示它是 1958 年 10 月 1 日。当我将此数据移动到 SQL Server 时,它被加载为 01-10-0258。所以我正在做上面的转换,它在 SQL Developer 中工作,但在 SSIS 中给出 ORA-01861 错误。
  • 如果您将它作为日期 移动,那么这不应该发生。如果您希望它作为 YYYY-MM-DD 格式的字符串,则只需使用 to_char()。
  • 列中的数据 - 20-JUL-58 转换:TO_CHAR(TO_DATE(date,'DD-MON-RR'),'YYYY-MM-DD')) 输出:1958-07- 20 如果我按日期执行:TO_DATE(date,'DD-MON-RR') 输出:20-JUL-58 as char YYYY-MM-DD TO_CHAR(date,'YYYY-MM-DD') 输出:0258- 07-20
  • 如果列是日期,那么 20-JUL-58 就是您的客户显示值的方式。 Oracle 有自己的内部表示。请阅读以前的 cmets 和我链接到的旧答案(至少是前半部分)。您只需要TO_CHAR(date,'YYYY-MM-DD')。如果这给你 0258-07-20 那么你的日期实际上是在 258 年 - 可能是因为插入时函数调用、隐式转换和 NLS 设置的类似混淆。

标签: oracle ssis


【解决方案1】:

TO_CHAR(date,'YYYY-MM-DD') 输出:0258-07-20

这意味着存储在数据库中的日期实际上是 258 年,而不是 1958 年。

当你这样做时

TO_CHAR(TO_DATE(date,'DD-MON-RR'),'YYYY-MM-DD')

您正在使用当前会话 NLS 日期格式将日期隐式转换为字符串,该格式会为您提供类似“20-JUL-58”的字符串。然后使用格式掩码“DD-MON-RR”将其显式转换回日期。

你正在有效地做:

TO_CHAR(TO_DATE(TO_CHAR(date,<nls_date_format>),'DD-MON-RR'),'YYYY-MM-DD')

在您的 SQL Developer 会话中有效:

TO_CHAR(TO_DATE(TO_CHAR(date,'DD-MON-RR'),'DD-MON-RR'),'YYYY-MM-DD')

因为中间字符串有一个两位数的年份 (58),而你有 the RR element,所以它变成了 1958。

当您从 SSIS 执行相同操作时,会话日期格式似乎具有 4 位数年份,因此它实际上是在执行以下操作:

TO_CHAR(TO_DATE(TO_CHAR(date,'DD-MM-YYYY'),'DD-MON-RR'),'YYYY-MM-DD')

现在中间字符串有一个 4 位数的年份 (0258),并且 RR 元素保持为 0258。

现在..您可以指定中间字符串格式而不是依赖 NLS,这至少会在两个会话之间保持一致:

TO_CHAR(TO_DATE(TO_CHAR(date,'DD-MON-RR'),'DD-MON-RR'),'YYYY-MM-DD')

或者让 SSIS 将其视为日期而不是字符串删除外部 to_char():

TO_DATE(TO_CHAR(date,'DD-MON-RR'),'DD-MON-RR')

另请注意,此转换以午夜值的时间部分结束;如果您的源日期有非午夜时间(可能不是因为它是根据 cmets 的出生日期)并且您想保留那些您应该在掩码中包含时间:

TO_DATE(TO_CHAR(date,'DD-MON-RR HH24:MI:SS'),'DD-MON-RR HH24:MI:SS')

但是这种双重转换对于不良数据来说是一种令人讨厌的解决方法,实际上您应该修复源表中的数据以具有正确的年份,并查看如何插入值以防止它们再次出错。

取决于它们错误的确切方式和原因 - 可能是插入期间不正确或隐含的格式掩码和/或意外的 NLS 设置 - 您可能需要评估您是否可以依赖年份的最后两位数字是正确和匹配的RR 元素的行为。也许您是否可以依靠正确的月份和日期部分。

【讨论】:

    猜你喜欢
    • 2014-04-27
    • 2016-04-02
    • 2015-02-13
    • 2021-10-26
    • 1970-01-01
    • 2017-08-24
    • 2015-01-11
    • 2010-11-26
    • 2012-10-09
    相关资源
    最近更新 更多