如何使用SSIS脚本任务将多个存储过程中的数据写入文件?

发布于 2024-11-29 20:03:23 字数 812 浏览 0 评论 0原文

我在 SQL Server 2008 中创建了一个 SSIS 包,需要它来迭代包含 ID、输出文件位置、要执行的 spname 的表,并包含表中每个 clientID 的数据。存储过程输出不同的报告并包含不同的字段,这是自动化当前使用多个 SSIS 包生成客户报告的过程所必需的,我想简化整个过程。

我创建的包包含一个 SQL 脚本组件,它将数据保存到一个变量对象,“每个容器”循环访问该对象变量并将数据保存到各个变量。但是,我需要脚本任务方面的帮助,因为我当前可以连接到 oledb 连接管理器,但是在尝试执行存储过程时脚本任务失败,可能是因为数据不是通过视图或表输出。

我是 VB.NET 脚本编写的新手,对 VB.NET 没有太多了解,我使用以下线程到达我当前的位置,并将 dbcommand 替换为我

Dim query As String = "Exec " & Dts.Variables("User::RunSP").Value

使用以下帖子到达我当前的位置:

从以下位置导出数据使用 SSIS 脚本任务将多个 SQL 表复制到不同的平面文件

当我执行脚本任务时,它在打开 trydbconnection 时失败。我尝试将其注释掉并在没有 try 部分的情况下运行脚本任务,但它仍然出错。

I have created an SSIS package in SQL Server 2008 that is required to iterate through a table that contains the ID, location to output files, spname to execute and contains data for each clientID within the table. The stored procedures output different reports and contain differing fields this is required to automate the current process of using multiple SSIS package for customer reports, I want to simplify the whole process.

The package I've created contains an SQL script component that saves the data to a variable object, a 'for each container' iterates through the object variable and saves the data to individual variables. However I require assistance with the script task as I can currently connect to the oledb connection manager however the script task is failing when trying to execute the stored procedure, maybe as the data is not output via view or a table.

I am new to VB.NET scripting and don't have that much knowledge of VB.NET, I used the following thread to get to my current position and replaced the dbcommand with an

Dim query As String = "Exec " & Dts.Variables("User::RunSP").Value

I used the following posting to get to my current position:

Exporting data from multiple SQL tables to different flat files using SSIS Script Task

When I execute the script task, it fails at the point where the try and dbconnection is opened. I've tried commenting this out and running the script task without the try section but it has continued to error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丑疤怪 2024-12-06 20:03:23

由于您使用我提供的示例作为问题的答案 使用 SSIS 脚本任务将数据从多个 SQL 表导出到不同的平面文件,我采用了相同的示例并对其进行了修改以运行存储过程。

它似乎工作没有任何问题。确保它与您想要做的事情相匹配。此示例使用 SSIS 2005SQL 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

表中的数据将如下面的屏幕截图所示。

Sample data

在 SSIS 包上,创建到 SQL Server 实例的连接管理器。

Connection manager

在 SSIS 包上,创建 4 个变量,即 DelimiterFileName、<代码>RunSP和<代码>SPsList。另外,将“执行 SQL 任务”、“Foreach 循环容器”和“脚本任务”放置在“控制流”选项卡上,如下面的屏幕截图所示。

变量和控制流

配置执行 SQL 任务以获取存储过程列表,如下面两个屏幕截图所示。

执行常规 SQL 任务

执行 SQL 任务结果集

配置 Foreach 循环容器以循环访问变量 SPsList 中存储的结果集,如下面两个屏幕截图所示。

Foreach 循环容器集合

在脚本任务的脚本部分中,单击设计脚本...按钮以打开 VSTA 编辑器。

Script Task

将 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 Tempempty

下面的屏幕截图显示了成功的包执行。

Success

文件夹路径 F:\Temp 现在包含包内脚本任务使用提供的数据生成的两个文件由单独的存储过程 SP1 和 SP2 执行。

F Temp with files

文件内容如下面的屏幕截图所示。文件内容以竖线分隔,您可以注意到数据与前面的屏幕截图中显示的表数据匹配。

文件 1

希望有帮助。

Since you were using the example that I provided as answer to the question Exporting data from multiple SQL tables to different flat files using SSIS Script Task, I took the same example and modified it to run the stored procedure.

It seems to work without any issues. Make sure it matches with what you are trying to do. This example uses SSIS 2005 with SQL Server 2008 R2 database.

Step-by-step process:

Create three tables namely dbo.TablesList, dbo.Source1 and dbo.Source2. Populate the tables with some sample data. Also, create two stored procedures named dbo.SP1 and dbo.SP2. Below given scripts does these tasks to create tables and stored procedures.

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

Data in the tables will look like as shown below in the screenshot.

Sample data

On the SSIS package, create a connection manager to the SQL Server instance.

Connection manager

On the SSIS package, create 4 variables namely Delimiter, FileName, RunSP and SPsList. Also, place an Execute SQL Task, Foreach Loop container and Script task on the Control Flow tab as shown in the below screenshot.

Variables and Control Flow

Configure the Execute SQL task to fetch the list of stored procedures as shown in the below two screenshots.

Execute SQL Task General

Execute SQL Task Result Set

Configure the Foreach Loop container to loop through the result set stored in the variable SPsList as shown in the below two screenshots.

Foreach Loop container Collection

Foreach Loop container Variable Mappings

In the Script task's Script section, click on the Design Script... button to bring the VSTA editor.

Script Task

Replace the VB.NET code with the below given code. After pasting the code, close the VSTA editor to save the changes.

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

Contents of the folder F:\Temp before executing the package. The folder is empty.

F Temp empty

Successful package execution is shown in the below screenshot.

Success

Folder path F:\Temp now contains the two files that were generated by the Script Task inside the package using the data provided by the individual stored procedures SP1 and SP2.

F Temp with files

Contents of the files are shown in the below screenshots. The file contents are pipe delimited and you can notice the data matches with the table data shown in the earlier screenshot.

File 1

File 2

Hope that helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文