如何在SSIS包中使用选定的SQL语句作为源变量?

时间:2015-03-05 00:16:26

标签: sql-server xml ssis

我创建了SSIS包,我需要使用FELC。循环之前的第一步是运行sql任务以获取旨在生成不同XML文件并存储在源表中的所有SQL语句。在FELC内部,我想处理语句以生成XML文件,并将它们发送到各种文件夹位置,其中包含来自源表的名称和目标文件夹。有数百个文件需要定期刷新。我不想为每个XML文件生成运行单个作业,而是将其合并为一个进程。 有可能吗?

2 个答案:

答案 0 :(得分:3)

这是Shred Recordset的基本模式。

Basic shred recordset pattern

我声明了3个变量:SourceQuery,CurrentQuery和rsQueryData。前两个是字符串,最后一个是对象类型

SQL - 获取源数据

这是我的查询。如果我取出过滤器,它会模拟你的表并导致失败的SQL语句。

SELECT
    ProcessID
,   Stmt_details
FROM
    ( 
        VALUES 
            ( 1, 'SELECT 1;', 1)
        ,   ( 20, 'SELECT 20;', 1)
        ,   ( 30, 'SELECT 1/0;', 0) 
    ) Stmt_collection (ProcessID, Stmt_details, xmlFlag)
WHERE
    xmlFlag = 1

使用Recordset = Full设置执行SQL任务,并将其分配给变量User :: rsQueryData,其在映射选项卡中的名称为0。

FELC

这是一个标准的Foreach ADO Recordset循环容器。我使用我的User :: rsQueryData作为源,因为我只关心第二个元素,顺序位置1,这是我映射的唯一内容。我将当前值分配给User :: CurrentStatement

SQL - 执行CurrentStatement

这是一个执行SQL任务,其源为Variable User :: CurrentStatement。没有涉及脚本。 FELC处理为此变量赋值。此任务使用相同变量作为其源。这就是本机SSIS开发人员如何解决问题的方法。如果您将脚本任务或组件作为第一种方法,那么您很可能做错了。

BIML

如果您正在进行任何级别的SSIS / SSRS / SSAS开发,那么 Bids Helper这是对Visual Studio的免费添加,使您的开发生活如此之多更轻松。我将在此处利用的功能是以声明方式定义SSIS包的功能。这种语言被称为商业智能标记语言,Biml,我喜欢它有很多原因,但在StackOverflow上,我喜欢它,因为我可以给你代码来重现完全我的解决方案。否则,我必须构建几百个屏幕截图,向您显示我必须单击并设置值。

或者,你 1.下载并安装BIDS Helper 2.打开现有的SSIS项目 3.右键单击项目并选择"添加新的Biml文件" 4.在生成的BimlScript.biml文件中,将其打开并将以下所有代码粘贴到其中 5.修复数据库连接字符串的值。这假设您在本地计算机上有一个名为Dev2014的实例 6.保存biml文件 7.右键单击BimlScript.biml并选择"生成SSIS包" 8.惊叹于添加到解决方案中的结果so_28867703.dtsx包

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2014;Initial Catalog=tempdb;Provider=SQLNCLI10.1;Integrated Security=SSPI;Auto Translate=False;" />
    </Connections>
    <Packages>
        <Package ConstraintMode="Linear" Name="so_28867703">
            <Variables>
                <Variable DataType="String" Name="QuerySource">SELECT ProcessID, Stmt_details FROM (VALUES (1, 'SELECT 1;', 1), (20, 'SELECT 20;', 1), (30, 'SELECT 1/0;', 0))Stmt_collection(ProcessID, Stmt_details, xmlFlag) WHERE xmlFlag = 1 </Variable>
                <Variable DataType="String" Name="CurrentStatement">This statement is invalid</Variable>
                <Variable DataType="Object" Name="rsQueryData"></Variable>
            </Variables>
            <Tasks>
                <ExecuteSQL 
                    ConnectionName="CM_OLE" 
                    Name="SQL - Get source data"
                    ResultSet="Full"
                    >
                    <VariableInput VariableName="User.QuerySource" />
                    <Results>
                        <Result VariableName="User.rsQueryData" Name="0" />
                    </Results>
                </ExecuteSQL>
                <ForEachAdoLoop 
                    SourceVariableName="User.rsQueryData" 
                    ConstraintMode="Linear" 
                    Name="FELC - Shred RS"
                    >
                    <VariableMappings>
                        <!--
                        0 based system
                        -->
                        <VariableMapping VariableName="User.CurrentStatement" Name="1" />
                    </VariableMappings>
                    <Tasks>
                        <ExecuteSQL ConnectionName="CM_OLE" Name="SQL - Execute CurrentStatement">
                            <VariableInput VariableName="User.CurrentStatement" />
                        </ExecuteSQL>
                    </Tasks>
                </ForEachAdoLoop>
            </Tasks>
        </Package>
    </Packages>
</Biml>

假设您已将连接字符串修复为有效实例,那么该包将运行。您可以在下面看到,如果在执行SQL任务上放置断点,它将亮起两次。如果您在CurrentStatement上有一个观察窗口,您可以看到它从设计时间值更改为从结果集中分割的值。

Animooted

虽然我们等待澄清XML和文件,但如果目标是从FELC获取查询并导出到文件,我回答https://stackoverflow.com/a/9105756/181965虽然在这种情况下,我会将您的包重组为只是数据流并消除了粉碎,因为没有必要使问题复杂化,导出单行N次。

答案 1 :(得分:-1)

如果我理解正确的话;您可以添加一个&#34;脚本任务&#34;从Toolbox到循环容器的第一步,将所选语句从数据库存储到全局变量中,并将其传递给下一步执行