我试图通过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
)正确导入?
答案 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 expressions和the SSIS doc for Casting中的格式,因为SSIS数据类型与SQL Server数据类型不同,即使它们干净地映射。例如,DT_GUID需要大括号,而UNIQUEIDENTIFIER则不需要。
根据我的经验,这表现得非常好。目前我唯一使用此方法的导入在相当适中的硬件上运行相当小。它只导入大约12,000条记录,但每条记录大约有4KB,并且有大约240个字段,并且它们正在转换其中的六个或七个。他们中的大多数都是通过添加破折号和花括号将字符串转换为DT_GUID,但其中一个正在纠正与此类似的畸形日期。包括数据写入在内的整个过程需要1到2秒。