【问题标题】:SSIS: Date format Issue csv file to a SQL Server table: DD and MM swappedSSIS:日期格式将 csv 文件发布到 SQL Server 表:DD 和 MM 交换
【发布时间】:2019-10-26 18:00:19
【问题描述】:

我有一个带有 MM/DD/YYYY 格式的日期列的 csv 文件。当我使用 SSIS 将 csv 文件加载到 SQL Server 表时,我希望具有以下格式:YYYY-MM-DD。

问题是当 csv 文件包含一个日期值在 1 到 12 之间的日期时,日期和月份会交换。

例子:

12/06/2019 in csv file -> 2019-06-12 in SQL Server table: DD and MM are swapped
MM/DD/YYYY  ->  YYYY-MM-DD

如何在 SQL Server 表中包含 2019-12-06?

提前感谢您的回答。

【问题讨论】:

  • 日期没有格式。它们是二进制值。如果您使用日期类型来存储日期,例如datedatetime 等,则存储的值将没有任何格式。仅当将字符串解析为日期或将日期格式化为字符串以进行显示时,格式才适用
  • 您确定您没有将 client 工具(SSMS 只是一个客户端工具)使用的格式与某些实际日期格式混淆吗? SSMS 使用 ISO8601 格式以避免混淆。其他客户端工具(例如桌面应用程序)将使用用户的区域设置来格式化日期
  • 12/06/2019 到底是什么意思? 6 月 12 日(今天)还是 12 月 6 日?如果是 6 月 12 日,则 CSV 日期为 DD/MM,而不是 MM/DD。用于解析平面文件中的日期和数字的区域性由平面文件源中的LocaleID 设置控制。如果您想要MM/DD,请将语言环境更改为en-US
  • 确定数据指的是 12 月 6 日吗?文件包含 今天的 记录的可能性要大得多(6 月 12 日)并且没有逆转。 YYYY-MM-DD 是用于显示日期的 ISO8601 格式。其组件的顺序不会改变

标签: sql-server csv datetime ssis etl


【解决方案1】:

我不明白为什么这不起作用。

我举了一个例子:

1. 建表

CREATE TABLE [dbo].[DateTable](
[TestDat] [datetime] NULL,
[TestDat1] [datetime] NULL,
[TestDat2] [datetime] NULL,
[TestDat3] [datetime] NULL) ON [PRIMARY]


2. 创建一个包含以下日期的 CSV 文件:
12/06/2019,01/06/2019,02/06/2019,03/06/2019

  1. 创建了一个只有数据流的 SSIS 包。数据流任务包含一个平面文件源和一个 OLE DB 目标。
    DataFlow 任务如下所示:

    OLE DB Destination 中的映射如下所示:

运行 SSIS 包后,我将以下数据填充到 SQL Server 表中。
它始终以 06 作为日期。

【讨论】:

    【解决方案2】:

    这是一个常见问题,因为在处理 MM/dd/yyyy 和 dd/MM/yyyy 日期字符串格式时,月份和日期都小于 12。

    由于 csv 文件是文本文件,日期存储为文本,因此将这些文件隐式转换为日期时间文件(sql 数据库)可能会导致此问题。

    确保正确转换日期的最佳方法是添加脚本组件,添加类型为DT_DATE 的输出列(例如:outDate)并使用DateTime.ParseExact() 函数强制使用MM/dd/yyyy 格式进行转换:

    Row.outDate = DateTime.ParseExact(Row.csvDateFiled,"MM/dd/yyy",System.Globalization.CultureInfo.InvariantCulture);
    

    您可以参考以下类似问题了解更多详情:

    【讨论】:

    • 您可以在平面文件源属性中指定 LocaleID。
    • 鉴于 当前日期(6 月 12 日),我怀疑 OP 将 MM/DD 与 DD/MM 混淆了,该文件实际上包含 6 月 12 日的记录,而不是 12 月6日
    • @PanagiotisKanavos 如果列数据类型设置为DT_DATE,这可能会起作用
    • 这就是已经发生的事情,日期以这种方式出现。脚本组件也会做同样的事情。您可以将 DateTime.Parseen-US 文化一起使用,而不是 DateTime.ParseExact
    • @PanagiotisKanavos 如果列数据类型是文本 DT_STRDT_WSTR 他必须手动验证日期(脚本/派生列)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 2016-01-02
    相关资源
    最近更新 更多