Hec*_*hez 2 c# sql excel ssis sql-server-2008
我遇到了SSIS包的问题.
正如大多数人所知,xls文件每张被限制为65,536行乘256列.因此,当查询提取超过记录限制(65,536)时,Excel目标步骤失败.
我收到以下错误消息.
Error: 0xC0202009 at Calidad VIDA, Excel Destination [82]: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80004005.
Error: 0xC0209029 at Calidad VIDA, Excel Destination [82]: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "input "Excel Destination Input" (93)" failed because error code 0xC020907B occurred, and the error row disposition on "input "Excel Destination Input" (93)" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure. Error: 0xC0047022 at Calidad VIDA, SSIS.Pipeline: SSIS Error Code DTS_E_PROCESSINPUTFAILED. The ProcessInput method on component "Excel Destination" (82) failed with error code 0xC0209029 while processing input "Excel Destination Input" (93). The identified component returned an error from the ProcessInput method. The error is specific to the component, but the error is fatal and will cause the Data Flow task to stop running. There may be error messages posted before this with more information about the failure.
Error: 0xC02020C4 at Calidad VIDA, OLE DB Source [1]: The attempt to add a row to the Data Flow task buffer failed with error code 0xC0047020.
Error: 0xC0047038 at Calidad VIDA, SSIS.Pipeline: SSIS Error Code DTS_E_PRIMEOUTPUTFAILED. The PrimeOutput method on component "OLE DB Source" (1) returned error code 0xC02020C4. The component returned a failure code when the pipeline engine called PrimeOutput(). The meaning of the failure code is defined by the component, but the error is fatal and the pipeline stopped executing. There may be error messages posted before this with more information about the failure.
该文件需要采用该格式,因为客户端没有更新的版本.他们不想购买许可证.有谁知道如何解决这个问题?我应该使用脚本任务并自己制作excel,或者我应该为每个循环创建一个并创建各种excels woorkbooks?
小智 6
下面是一个可能的选项,您可以使用SSIS根据每个Excel工作表要写入的记录数来动态创建Excel工作表.这不涉及脚本任务.以下示例描述了如何使用"执行SQL任务","For循环容器"和"数据流任务"来实现此目的.该示例是使用创建的SSIS 2008 R2.
分步过程:
在SQL Server数据库中,运行" SQL脚本"部分下提供的脚本.这些脚本将创建一个名为表dbo.SQLData,然后将填充用乘法数据表自1 x 1通20 x 40,从而创造800个记录.该脚本还会创建一个名为的存储过程dbo.FetchData,该存储过程将在SSIS包中使用.
在SSIS包上,创建9个变量,如屏幕截图#1所示.以下步骤描述了如何配置这些变量.
将变量ExcelSheetMaxRows设置为值80.此变量表示每个Excel工作表要写入的行数.您可以将其设置为您选择的值.在您的情况下,这将是65,535(您可能希望为标题列名称留下1行).
使用值设置变量SQLFetchTotalRowsSELECT COUNT(Id) AS TotalRows FROM dbo.SQLData.此变量包含用于从表中获取总行数的查询.
选择变量StartIndex,然后按F4选择"属性" .将属性EvaluateAsExpression设置为True,将属性Expression设置为值(@[User::Loop] * @[User::ExcelSheetMaxRows]) + 1.参见截图#2.
选择变量EndIndex,然后按F4选择"属性" .将属性EvaluateAsExpression设置为True,将属性Expression设置为值(@[User::Loop] + 1) * @[User::ExcelSheetMaxRows].参见截图#3.
选择变量ExcelSheetName,然后按F4选择"属性" .将属性EvaluateAsExpression设置为True,将属性Expression设置为值"Sheet" + (DT_WSTR,12) (@[User::Loop] + 1).参见截图#4.
选择变量SQLFetchData,然后按F4选择"属性" .将属性EvaluateAsExpression设置为True,将属性Expression设置为值"EXEC dbo.FetchData " + (DT_WSTR, 15) @[User::StartIndex] + "," + (DT_WSTR, 15) @[User::EndIndex].参见截图#5.
选择变量ExcelTable并按F4选择"属性" .将属性EvaluateAsExpression设置为True,将属性Expression设置为ExcelTable Variable Value部分下提供的值.参见截屏#6.
在SSIS包的"控制流"选项卡上,放置一个执行SQL任务并对其进行配置,如屏幕截图#7和#8所示.此任务将获取记录计数.
在SSIS包的"控制流"选项卡上,放置一个For循环容器并按照屏幕截图#9所示进行配置.请注意这是For Loop而不是Foreach Loop.此循环将根据要在每个Excel工作表中显示的记录数以及表中找到的记录总数执行.
创建一个Excel 97-2003格式的Excel电子表格,其中包含.xls扩展名,如屏幕截图#10所示.我在**C:\ temp**中创建了该文件
在SSIS包的连接管理器上,创建一个名为SQLServer指向SQL Server 的OLE DB连接和一个名为Excel指向新创建的Excel文件的Excel连接.
单击Excel连接,然后选择"属性".将属性DelayValidation从False更改为True,这样当我们在数据流任务中切换到使用变量创建工作表时,我们将不会收到任何错误消息.参见截图#11.
在For循环容器中,放置一个执行SQL任务并对其进行配置,如屏幕截图#12所示.此任务将根据要求创建Excel工作表.
在For循环容器内,放置数据流任务.配置任务后,"控制流"选项卡应如屏幕截图#13所示.
在数据流任务中,放置OLE DB源以使用存储过程从SQL Server读取数据.配置OLE DB源,如屏幕截图#14和#15所示.
在"数据流任务"内,放置Excel目标以将数据插入Excel工作表.配置Excel目标,如屏幕截图#16和#17所示.
配置数据流任务后,它应如屏幕截图#18所示.
删除在步骤12中创建的Excel文件,因为该包将在执行时自动创建该文件.如果没有删除,该包将抛出Sheet1已存在的异常.此示例使用路径C:\ temp \,屏幕截图#19显示该路径中没有文件.
屏幕截图#20和#21显示了控制流和数据流任务中的包执行.
屏幕截图#22显示文件ExcelData.xls已在路径C:\ temp中创建.记住,早些时候这条路是空的.由于表中有800行,我们将包变量ExcelSheetMaxRows设置为每张表创建80行.因此,Excel文件有10张.参见截图#23.
NOTE:我在这个例子中没有做的一件事是检查文件ExcelData.xls是否已经存在于路径C:\ temp中.如果存在,则应在执行任务之前删除该文件.这可以通过创建保存Excel文件路径的变量并使用文件系统任务在执行第一个执行SQL任务之前删除文件来实现.
希望有所帮助.
ExcelTable变量值:
"CREATE TABLE `" + @[User::ExcelSheetName] + "`(`Id` Long, `Number1` Long, `Number2` Long, `Value` Long)"
Run Code Online (Sandbox Code Playgroud)
SQL脚本:
--Create table
CREATE TABLE [dbo].[SQLData](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Number1] [int] NOT NULL,
[Number2] [int] NOT NULL,
[Value] [int] NOT NULL,
CONSTRAINT [PK_Multiplication] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO
--Populate table with data
SET NOCOUNT ON
DECLARE @OuterLoop INT
DECLARE @InnerLoop INT
SELECT @OuterLoop = 1
WHILE @OuterLoop <= 20 BEGIN
SELECT @InnerLoop = 1
WHILE @InnerLoop <= 40 BEGIN
INSERT INTO dbo.SQLData (Number1, Number2, Value)
VALUES (@OuterLoop, @InnerLoop, @OuterLoop * @InnerLoop)
SET @InnerLoop = @InnerLoop + 1
END
SET @OuterLoop = @OuterLoop + 1
END
SET NOCOUNT OFF
--Create stored procedure
CREATE PROCEDURE [dbo].[FetchData]
(
@StartIndex INT
, @EndIndex INT
)
AS
BEGIN
SELECT Id
, Number1
, Number2
, Value
FROM (
SELECT RANK() OVER(ORDER BY Id) AS RowNumber
, Id
, Number1
, Number2
, Value
FROM dbo.SQLData
) T1
WHERE RowNumber BETWEEN @StartIndex AND @EndIndex
END
GO
Run Code Online (Sandbox Code Playgroud)
截图#1:

截图#2:

截图#3:

截图#4:

截图#5:

截图#6:

截图#7:

截图#8:

截图#9:

截图#10:

截图#11:

截图#12:

截图#13:

截图#14:

截图#15:

截图#16:

截图#17:

截图#18:

截图#19:

截图#20:

屏幕截图#21:

截图#22:

屏幕截图#23:
