我在SQL Server 2008中创建了一个SSIS包,需要迭代一个包含ID的表,输出文件的位置,要执行的spname以及包含表中每个clientID的数据。存储过程输出不同的报告并包含不同的字段,这是自动化当前使用多个SSIS包进行客户报告的过程所需的,我希望简化整个过程。
我创建的包中包含一个SQL脚本组件,用于将数据保存到变量对象,'for each container'遍历对象变量并将数据保存到单个变量中。但是我需要脚本任务的帮助,因为我当前可以连接到oledb连接管理器,但是在尝试执行存储过程时脚本任务失败,可能因为数据不是通过视图或表输出的。
我是VB.NET脚本的新手,并且对VB.NET没有太多了解,我使用以下线程来获取当前位置并用
替换dbcommandDim query As String = "Exec " & Dts.Variables("User::RunSP").Value
我使用以下帖子来达到目前的位置:
Exporting data from multiple SQL tables to different flat files using SSIS Script Task
执行脚本任务时,它会在try
和dbconnection
打开时失败。我已尝试对此进行评论并在没有try
部分的情况下运行脚本任务,但它仍然出错。
答案 0 :(得分:3)
由于您使用我提供的示例作为问题Exporting data from multiple SQL tables to different flat files using SSIS Script Task的答案,因此我采用了相同的示例并对其进行了修改以运行存储过程。
似乎没有任何问题。确保它与您尝试的操作相匹配。此示例使用SSIS 2005
和SQL Server 2008 R2
数据库。
分步流程:
创建三个表,即dbo.TablesList,dbo.Source1和dbo.Source2。使用一些示例数据填充表格。此外,创建两个名为dbo.SP1和dbo.SP2的存储过程。下面给出的脚本执行这些任务来创建表和存储过程。
CREATE TABLE [dbo].[Source1](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ItemNumber] [varchar](20) NOT NULL,
[ItemName] [varchar](50) NOT NULL,
CONSTRAINT [PK_Source1] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Source2](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Country] [varchar](20) NOT NULL,
[StateProvince] [varchar](50) NOT NULL,
CONSTRAINT [PK_Source2] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO
CREATE TABLE [dbo].[TablesList](
[Id] [int] IDENTITY(1,1) NOT NULL,
[SPName] [varchar](50) NOT NULL,
[FilePath] [varchar](255) NOT NULL,
CONSTRAINT [PK_Tables] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO
INSERT INTO dbo.TablesList (FilePath, SPName) VALUES
('F:\Temp\Item_Details.txt', 'SP1'),
('F:\Temp\Country_StateProvince.txt', 'SP2');
GO
INSERT INTO dbo.Source1 (ItemNumber, ItemName) VALUES
('34534', 'Keyboard'),
('24312', 'Mouse'),
('78555', 'Monitor');
GO
CREATE PROCEDURE [dbo].[SP1]
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM dbo.Source1
END
GO
CREATE PROCEDURE [dbo].[SP2]
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM dbo.Source2
END
GO
表格中的数据如下图所示。
在SSIS包上,为SQL Server实例创建连接管理器。
在SSIS包上,创建4个变量,即Delimiter
,FileName
,RunSP
和SPsList
。此外,在“控制流”选项卡上放置“执行SQL任务”,“Foreach循环”容器和“脚本”任务,如下面的屏幕截图所示。
配置执行SQL任务以获取存储过程列表,如以下两个屏幕截图所示。
配置Foreach循环容器以循环存储在变量SPsList中的结果集,如以下两个屏幕截图所示。
在“脚本任务”的“脚本”部分中,单击“设计脚本...”按钮以启用VSTA编辑器。
用下面给出的代码替换VB.NET代码。粘贴代码后,关闭VSTA编辑器以保存更改。
Imports System
Imports System.Data
Imports System.Data.OleDb
Imports System.IO
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Public Class ScriptMain
Public Sub Main()
Dim varCollection As Variables = Nothing
Dts.VariableDispenser.LockForRead("User::FileName")
Dts.VariableDispenser.LockForRead("User::Delimiter")
Dts.VariableDispenser.LockForRead("User::RunSP")
Dts.VariableDispenser.GetVariables(varCollection)
Dim fileName As String = varCollection("User::FileName").Value.ToString()
Dim query As String = "EXEC " & varCollection("User::RunSP").Value.ToString()
Dim delimiter As String = varCollection("User::Delimiter").Value.ToString()
Dim writer As StreamWriter = Nothing
Dim connection As OleDbConnection = New OleDbConnection(Dts.Connections("Learn2008R2").ConnectionString)
Dim command As OleDbCommand = Nothing
Dim reader As OleDbDataReader = Nothing
Try
If File.Exists(fileName) Then
File.Delete(fileName)
End If
connection.Open()
command = New OleDbCommand(query, connection)
reader = command.ExecuteReader()
writer = New System.IO.StreamWriter(fileName)
Dim row As Integer = 0
Dim header As Integer = 0
Dim fieldCount As Integer = reader.FieldCount - 1
If row = 0 Then
While header <= fieldCount
If header <> fieldCount Then
writer.Write(reader.GetName(header).ToString() & delimiter)
Else
writer.WriteLine(reader.GetName(header).ToString())
End If
header += 1
End While
End If
If reader.HasRows Then
While reader.Read()
Dim counter As Integer = 0
While counter <= fieldCount
If counter <> fieldCount Then
writer.Write(reader(counter).ToString() & delimiter)
Else
writer.WriteLine(reader(counter).ToString())
End If
counter += 1
End While
End While
End If
Catch ex As Exception
Throw ex
Finally
connection.Close()
writer.Close()
End Try
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
执行包之前文件夹F:\ Temp的内容。该文件夹为空。
成功的包执行显示在下面的屏幕截图中。
文件夹路径F:\ Temp现在包含使用各个存储过程SP1和SP2提供的数据由程序包内的脚本任务生成的两个文件。
文件内容显示在以下屏幕截图中。文件内容以管道分隔,您可以注意到数据与早期屏幕截图中显示的表数据匹配。
希望有所帮助。