我正在使用SSIS执行数据迁移.
我正在使用Excel目标文件来输出出错的所有内容.
在这个Excel文件中,我想输出两个错误列(错误号和错误列)以及输入组件中的所有列.
这几乎正常工作,除非我的字符串列超过255个字符.当我设置Excel目标时,我创建了一个新表.
Create Table语句将Longtext正确定义为数据类型:
CREATE TABLE `My data` (
`ErrorCode` Long,
`ErrorColumn` Long,
`ID` Long,
`MyStringColumn` LongText
)
Run Code Online (Sandbox Code Playgroud)
这是第一次工作.然后,我从Excel文件中删除所有数据,因为我想在输出错误之前清理excel文件.
当我在Package设计器中返回时,我的列定义搞砸了.每个文本列都被处理为nvarchar(255),而不再是ntext.当我的数据超过255时,这会破坏我的组件.
如何正确管理Excel目的地?
谢谢
[编辑]由于我不确定我的解释,这是运行任务时的错误消息:
Error: 0xC0202009 at MyDataTask, To Errors file [294]: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E21.
Error: 0xC0202025 at MyDataTask, To Errors file [294]: Cannot create an OLE DB accessor. Verify that the column metadata is valid.
Error: 0xC004701A at MyDataTask, SSIS.Pipeline: component "To Errors file" (294) failed the pre-execute phase and returned error code 0xC0202025.
Run Code Online (Sandbox Code Playgroud)
小智 6
在涉及Excel目标的SSIS包中,我使用了Excel模板文件格式策略来克服您遇到的错误.
这是一个示例,首先显示如何模拟您的错误消息,然后显示如何解决它.该示例使用SSIS 2008 R2和Excel 97-2003.
创建具有两个字段的简单表Id
和Description
.用几个记录填充表格.
创建了具有单个数据流任务的SSIS包,并且数据流任务的配置如下所示.它基本上从上面提到的SQL Server表中读取数据,然后尝试将Description列转换为Unicode字符长度设置为20的文本.
由于表有两行,其描述列的长度超过20个字符,因此数据转换转换的默认错误配置设置将使包失败.但是,我们需要重定向所有错误行.因此,必须更改数据转换任务上的错误配置,如下所示,以重定向错误行.
然后,我将错误输出重定向到Excel目标,该目标配置为将输出保存到路径中的文件C:\temp\Errors.xls
.首次执行包是成功的,因为Excel文件一开始就是空的.
该文件将包含表中的两行,因为它们都会遇到截断错误,因此会重定向到错误输出.
删除Excel文件中的内容而不更改列标题后,如果我们再次执行包,它将失败.
失败的原因是由于下面显示的错误消息.
这样就完成了问题中提到的错误的模拟.这是解决问题的一种可能方式.
删除错误输出重定向到的现有Excel文件目标.使用路径创建新的Excel连接管理器C:\temp\Template.xls
.放置一个新的Excel目标并将其指向新的Excel连接管理器,并使用Excel目标上的"新建"按钮在新的Excel文件中创建工作表.
创建两个名为TemplatePath
和的包变量ActualPath
.TemplatePath应该具有值C:\temp\Template.xls
,ActualPath应该具有该值C:\temp\Errors.xls
.实际路径是您希望创建文件的路径.
右键单击Excel连接管理器并将该DelayValidation
属性设置为False,并将ServerName
表达式设置为变量@ [User :: ActualPath].如果文件C:\temp\Errors.xls
不存在,DelayValidation将确保包在设计时不会抛出错误.设置ServerName表达式将确保程序包将使用变量ActualPath中提到的文件路径来生成文件.
在"控制流"选项卡上,将"文件系统任务"放在"数据流"任务上方.
配置文件系统任务,如下所示.因此,文件系统任务将复制模板文件, C:\temp\Template.xls
并在C:\temp\Errors.xls
每次运行包时创建新的目标文件.如果文件C:\temp\Errors.xls
已存在,则文件系统任务将在文件系统任务中的OverwriteDestination
属性设置为True时覆盖该文件.
现在,您可以继续多次运行该程序包.程序包不会失败,您只需要上次执行时的错误消息,而无需手动清除Excel文件内容.
希望有所帮助.
[编辑]由史蒂夫B.添加,直接在帖子中提供更多细节,因为它的评论太长了
在我的解决方案中,我在我的SSIS项目中有两个Excel文件:Errors_Design_Template.xls
和Errors_Template.xls'. The former file contains my sheets with the headers and one line of data (using formulas like
= Rept("A",1024)`用于最大长度为1024的输入列),后者在没有第一行数据的情况下完全相同.
这两个文件都在包的开头从源目录复制到临时目录.我使用两个文件,因为我想保持设计时间验证,并且我指向Excel连接中的模板文件的副本.我正在复制模板文件,因为我经常执行我的包的单个数据流任务,我想填充临时文件,而不是我的项目中的模板文件(必须保持空,但标题和第一个虚拟数据线).
我还使用了两个变量,一个用于Excel连接表达式,一个用于实际输出文件.我还必须编写一个脚本,将两个变量作为输入.ActualFilePath是读/写.该脚本在运行时将ActualFilePath的值复制到ErrorFilePath变量.(我现在没有源代码,但是如果有帮助我可以在下周粘贴它).
同时使用此组件允许我在设计时将Excel连接指向设计文件,并在运行时指向实际的错误文件,而不必将delayvalidation设置为true.