我正在开发一个SSIS流程,该流程将从Excel文件中提取数据并将其加载到SQL Server DB中。
对于源文件中的每个工作表,我都有单独的数据流。 Excel文件包含不同格式的数据(但也可以包含无效数据),因此我正在使用显式类型转换。
对于日期,我在SQL语句中使用cdate(f1) as f1
构造(数字根据列而变化),以防止SSIS自行决定日期格式。
此通常正常工作。但是,在某些情况下,当我尝试运行该过程时会引发错误,并且数据中存在非法值:
[SSIS.Pipeline]错误:SSIS错误代码DTS_E_PRIMEOUTPUTFAILED。的 My_Excel_Source上的PrimeOutput方法返回错误代码0x80040E21。 当管道引擎调用时,组件返回失败代码 PrimeOutput()。故障代码的含义由 组件,但错误是致命的,并且管道停止执行。 在此之前可能会发布错误消息,并提供更多信息 关于失败。
我没有其他错误。
当我尝试从Excel Source Editor窗口中预览结果时,确实如期获得了带有数据样本的数据网格。当有非法数据时,将显示文本-很好。在其他数据流中,将返回值“ 1899-12-30”,我可以用它做任何想做的事情。
我尝试将此列的数据类型显式定义为DT_DATE,但仍然收到错误。我已经将各种可能的属性设置与其他数据流(不会引发此错误)进行了比较,并且看起来都一样。 我还尝试将Excel Source组件的错误处理行为更改为“忽略失败”,而不是“失败组件”-无效。
我应该注意,那里没有可能的资源问题。我只处理每张纸中的几行(最多几十行)。
我希望当源单元格包含非法值时,Excel Source组件将返回值“ 1899-12-30”,而不是使数据流崩溃。
谢谢, 大卫
答案 0 :(得分:0)
如果您想让Excel控制日期解析,我会尝试一些SQL表达式
CASE
WHEN IsDate(f1) THEN CDate(f1)
ELSE NULL
END AS f1
因此,如果f1
解析为日期,则将其强制转换为Date,否则返回NULL。
如果愿意,可以将NULL替换为您可能希望的任何哨兵值,例如CDate('1899-12-30')
。
在没有IsDate保护的情况下,Excel OLEDB连接器会执行您要求的操作-尝试将表达式强制转换为最新日期,然后失败。
测试每个单元格是否能够进行转换以及在失败的情况下显示文本的功能是Excel应用程序的一部分,而不是Excel OLEDB连接器。因此,我们需要在此处使用上面的CASE表达式进行仿真。