【问题标题】:How to split table data into separate named Excel files using an SSIS package?如何使用 SSIS 包将表数据拆分为单独的命名 Excel 文件?
【发布时间】:2009-02-06 16:10:22
【问题描述】:

我正在处理来自 SQL Server 的一组数据,我想将这些数据放入一组 Excel 文件中。此任务需要自动运行以每月运行一次。数据看起来像

Site    ID      FirstName   LastName
------  ------- ---------   ---------
North   111     Jim         Smith
North   112     Tim         Johnson
North   113     Sachin      Tedulkar
South   201     Horatio     Alger
South   205     Jimi        Hendrix
South   215     Bugs        Bunny

我希望结果看起来像

In Excel file named North.xls

ID      FirstName   LastName
111     Jim         Smith
112     Tim         Johnson
113     Sachin      Tedulkar

In Excel file named South.xls

ID      FirstName   LastName
201     Horatio     Alger
205     Jimi        Hendrix
215     Bugs        Bunny

我想拆分站点列中有 70 到 100 个值。我正在使用 SSIS 执行此任务,但是在使用 OLE DB 源任务从 SQL Server 中提取数据后,我遇到了困难。接下来应该怎么做?如果使用其他工具有更简单的方法可以做到这一点,我也愿意接受。

【问题讨论】:

    标签: sql-server excel ssis


    【解决方案1】:

    您现在可能已经找到了问题的答案。这适用于可能偶然发现此问题的其他用户。以下示例显示了如何为可能存在的任意数量的站点动态地实现这一点。该示例是使用 SSIS 2008 R2SQL Server 2008 R2 数据库创建的。

    分步过程:

    1. 在 SQL Server 数据库中执行 SQL 脚本部分下给出的脚本,以创建一个名为 dbo.Source 的表并填充数据(类似于问题中给出的数据)。它还会创建一个名为 dbo.GetSiteData 的存储过程。

    2. 在 SSIS 包的连接上,创建一个 OLE DB 连接以连接到 SQL Server。我们将在后面的步骤中连接 Excel。

    3. 在 SSIS 包上,创建 6 个变量,如屏幕截图 #1 所示。用值Template 填充变量Site,这是一个用于评估其他表达式的示例值。将变量 SQLUniqueSites 设置为值 SELECT DISTINCT Site FROM dbo.SourceData。将变量 ExcelFolder 设置为值为 C:\temp\

    4. 选择变量ExcelFilePath并按F4查看属性。将属性 EvaluateAsExpression 更改为 True,并将属性 Expression 设置为值 @[User::ExcelFolder] + @[User::Site] + ".xls"。请参阅屏幕截图 #2

    5. 选择变量ExcelSheet并按F4查看属性。将属性 EvaluateAsExpression 更改为 True 并将属性 Expression 设置为在 ExcelSheet 变量值 下给出的值。请参阅屏幕截图 #3

    6. 在 SSIS 包的“控制流”选项卡上,放置 Execute SQL Task 并按照屏幕截图 #4 和 #5 所示进行配置。此任务将获取唯一的站点名称。

    7. 在 SSIS 包的“控制流”选项卡上,在“执行 SQL 任务”之后放置 Foreach Loop container,并配置 Foreach 循环容器,如屏幕截图 #6 和 #7 这个循环将遍历结果集并将每个站点读入一个变量。然后,此变量用于为 Excel 文件提供名称,以及为即将添加的数据流任务中的存储过程提供参数。

    8. 在 Foreach 循环容器内,放置 Execute SQL Task,然后放置 Data Flow Task。此时,“控制流”选项卡应如屏幕截图 #8 所示。此时您的包裹可能会显示错误,我们将在接下来的步骤中尽快修复。我们将配置数据流任务,然后在 Foreach 循环容器中返回执行 SQL 任务。

    9. 在数据流任务中,放置一个OLE DB Source 并按照屏幕截图 #9 和 #11 所示进行配置。这将根据给定站点从表中获取数据。点击Parameters...按钮设置查询参数。

    10. 如果表字段数据类型是VARCHAR,那么我们需要将其转换为NVARCHAR(unicode格式),否则不需要这一步。在数据流任务中,在 OLE DB 源之后放置一个Data Conversion 转换并按照屏幕截图 #12 所示进行配置。

    11. 接下来,在数据流任务中,放置一个 Excel 目标,单击第一个新建... 按钮,如屏幕截图 #13 所示。

    12. 在 Excel 连接管理器对话框中,提供 Excel 文件路径并单击确定。请参阅屏幕截图 #14。返回 Excel 目标,单击第二个 New... 按钮,如屏幕截图 #15 所示。在 Create Table 对话框中,确保脚本如屏幕截图 #16 中所示,然后单击 OK。当屏幕截图 #17 中显示警告时,单击“确定”。从 Excel 工作表的名称 下拉列表中选择值 Template,如屏幕截图 #18 所示。如屏幕截图 #19 所示配置列。

    13. 在 SSIS 包的连接管理器上,选择新创建的 Excel 连接管理器并按 F4 键查看属性。将 Name 属性值更改为 Excel。将 DelayValidation 更改为 True,这样如果 Template.xls 文件不存在,您就不会收到错误消息。将 ServerName 表达式设置为值为 @[USer::ExcelFilePath]。请参阅屏幕截图 #20NOTE: 应该已经在路径 C:\temp\Template.xls 中创建了一个 Excel 文件。您可能希望保存它,以便在将来的设计更改期间不会遇到。如果文件被删除,您仍然可以重新创建它。

    14. 返回 Excel 目标并按照屏幕截图 #21 所示进行配置。配置数据流任务后,它应如屏幕截图 #22 所示。

    15. 返回控制流选项卡,在 Foreach 循环容器中配置执行 SQL 任务,如屏幕截图 #23 所示。此任务将为每个站点名称创建新的 Excel 电子表格。

    16. 屏幕截图 #24 显示文件夹 c:\temp\ 包执行之前的内容。

    17. 屏幕截图 #25 和 #26 显示了包的执行情况。

    18. 屏幕截图 #27 显示文件夹 c:\temp\ 包执行之后的内容。

    19. 屏幕截图 #28 和 #29 显示了新创建的 Excel 电子表格 North.xls 和 South.xls 的内容。两张表都包含同名站点各自的数据。

    希望对您有所帮助。

    ExcelSheet 变量值:

    CREATE TABLE `Template` (`Id` Long, `FirstName` LongText, `LastName` LongText)
    

    SQL 脚本:

    CREATE TABLE [dbo].[SourceData](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [Site] [varchar](50) NOT NULL,
        [FirstName] [varchar](40) NOT NULL,
        [LastName] [varchar](40) NOT NULL,
    CONSTRAINT [PK_SourceData] PRIMARY KEY CLUSTERED ([Id] ASC)
    ) ON [PRIMARY]
    GO
    
    INSERT INTO dbo.SourceData (Site, FirstName, LastName) VALUES
        ('North', 'Jim', 'Smith'),
        ('North', 'Tim', 'Johnson'),
        ('North', 'Sachin', 'Tendulkar'),
        ('South', 'Horatio', 'Alger'),
        ('South', 'Jimi', 'Hendrix'),
        ('South', 'Bugs', 'Bunny');
    GO
    
    CREATE PROCEDURE dbo.GetSiteData
    (
        @Site   VARCHAR(50)
    )
    AS
    BEGIN   
        SET NOCOUNT ON;
    
        SELECT  Id 
            ,   FirstName
            ,   LastName
        FROM    dbo.SourceData
        WHERE   Site = @Site
    END 
    GO
    

    屏幕截图 #1:

    屏幕截图 #2:

    截图#3:

    屏幕截图 #4:

    屏幕截图 #5:

    屏幕截图 #6:

    截图#7:

    截图#8:

    屏幕截图 #9:

    屏幕截图 #10:

    屏幕截图 #11:

    屏幕截图 #12:

    屏幕截图 #13:

    屏幕截图 #14:

    屏幕截图 #15:

    屏幕截图 #16:

    屏幕截图 #17:

    屏幕截图 #18:

    屏幕截图 #19:

    屏幕截图 #20:

    屏幕截图 #21:

    屏幕截图 #22:

    屏幕截图 #23:

    屏幕截图 #24:

    屏幕截图 #25:

    屏幕截图 #26:

    屏幕截图 #27:

    屏幕截图 #28:

    屏幕截图 #29:

    【讨论】:

      【解决方案2】:

      我认为 SSIS 是一个很好的工具,您有多种选择。

      基本上,您可以使用多播和条件拆分对象来实现您想要的。

      我会这样做:

      1) 我将创建两个 MS Excel 文件,其中包含我希望看到的所有数据。删除数据并将其保留为模板文件并为完整文件制作副本。

      2) 在连接管理器中设置到这些文件的文件连接。

      3) 创建一个文件系统任务,在作业开始时用模板覆盖完整文件(其他方法可以做到这一点,但我最喜欢这个)。

      4) 添加数据流任务并在其中放入一个 OLE DB 源、一个多播、两个条件拆分和两个 MS Excel 目标。

      5) 配置每一个,你应该完成。配置非常直观,按照我上面的顺序。

      【讨论】:

      • 虽然我在示例中只包含了 2 个值,但仍有大约 70 到 100 个值必须拆分为 Excel 文件。我是否必须为每个文件手动创建一个文件?谢谢。
      【解决方案3】:

      不确定这是否可行,但将所有条件查询与文件名的另一个字段一起放在一个表中。然后使用 for 循环遍历其中的每一个并动态修改转换任务的 select 子句。 SSIS 将这些动态修改称为 - 表达式。

      您在语句/条件表上进行选择,然后将其放入对象变量中。然后在 for 循环中使用对象变量。

      我唯一不确定的是到 excel 文件名的映射。

      编辑:也发现了这个,它使用链接服务器http://codebetter.com/blogs/raymond.lewallen/archive/2005/05/04/62781.aspx

      【讨论】:

        【解决方案4】:

        我发现问题出在 excel 目的地的解决方案。我重新安装了 Microsoft 访问引擎 Redistributable(32 位版本)。一切正常。 我遇到了 64 位和 32 位的问题,因为我的系统是 64 位,所以它们不兼容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-13
          • 1970-01-01
          • 1970-01-01
          • 2018-02-17
          相关资源
          最近更新 更多