带有DateTime2列的SSIS数据流CSV到SQL Server

时间:2015-05-05 20:20:22

标签: sql-server ssis

我试图通过SSIS数据流任务将平面文件加载到SQL Server中。就文件而言,我正在以这种形状20140311115000获取列,如果我转向Fast Parse: False,如果我将列更改为2014-03-11 11:50:00,我可以导入该列。这并不是最佳的,因为我无法控制我们给出的上游文件,而且我不会解析每个列/行/表。在我的文件连接中,我将列定义为:DT_DBTIMESTAMP2。在压缩格式中,我收到以下错误:

[ADO NET Destination [2]] Error: System.ArgumentOutOfRangeException:
Year, Month, and Day parameters describe an un-representable DateTime.
at System.DateTime.DateToTicks(Int32 year, Int32 month, Int32 day)...`

有没有办法让较短的列格式(20140311115000)正确导入?

1 个答案:

答案 0 :(得分:5)

扩展我的评论,因为这似乎是一个可接受的答案:

我会在SSIS中使用派生列处理此问题。它有一些主要优点:首先,它使用与导入过程的其余部分相同的解析方法,因此您不必担心解析字段;第二,它都是在内存中完成的,因此您不会将数据写入磁盘两次;第三,它的SSIS进行转换而不是SQL Server引擎,因此它不会遭受资源争用(特别是如果你的SSIS在另一台服务器上);四,Derived Columns use synchronous stream processing,速度和它一样快。

我这样做的方法是将CSV文件中的字段定义为长度为14的字符串(DT_STR)。我倾向于重命名CSV的输入列&# 34; {SourceColumn} _STR"或者" {SourceColumn} _RAW",因为你需要有唯一的输入和输出列名,这让我可以使用" {SourceColumn}"稍后将获取派生列的名称。 IMO,这使得映射目的地变得更加容易一些。如果您没有更改数据类型,则可以更换列,但如果更改数据类型,则还必须为其指定新的列名AFAIK。

因此,接下来,您将在数据流任务中正常创建平面文件数据源。接下来,添加派生列转换。编辑转换,为新列命名为" {SourceColumn}",将其配置为Add as a New Column,并格式化字符串并使用类似的表达式对其进行转换:

(DT_DBTIMESTAMP2, 2)(SUBSTRING(MyDateColumn,1,4) + "-" + SUBSTRING(MyDateColumn,5,2) + "-" + SUBSTRING(MyDateColumn,7,2) + " " + SUBSTRING(MyDateColumn,9,2) + ":" + SUBSTRING(MyDateColumn,11,2) + ":" + SUBSTRING(MyDateColumn,13,2))

我倾向于使用the TechNet wiki page for SSIS expressionsthe SSIS doc for Casting中的格式,因为SSIS数据类型与SQL Server数据类型不同,即使它们干净地映射。例如,DT_GUID需要大括号,而UNIQUEIDENTIFIER则不需要。

根据我的经验,这表现得非常好。目前我唯一使用此方法的导入在相当适中的硬件上运行相当小。它只导入大约12,000条记录,但每条记录大约有4KB,并且有大约240个字段,并且它们正在转换其中的六个或七个。他们中的大多数都是通过添加破折号和花括号将字符串转换为DT_GUID,但其中一个正在纠正与此类似的畸形日期。包括数据写入在内的整个过程需要1到2秒。