【问题标题】:SSIS For Loop resetting the variable valueSSIS For循环重置变量值
【发布时间】:2014-09-16 21:45:14
【问题描述】:

在 SSIS (MS Visual Studio 2010) 中,我创建了一个带有单行输出 (int32) 的 SQL 任务,该任务传递给 User::Variable。然后我有一个“For Loop”,我想运行与 SQL 任务查询中的整数相等的次数。我已经使用以下内容设置了 For 循环:

InitExpression: @Start = 1
EvalExpression: @Variable >= @Start
AssignExpression: @Start = @Start+1

在我的测试示例中,@Variable 通过 SQL 任务查询设置为 4,并且循环在第一个循环中运行良好,但随后立即完成报告包成功执行(仅在 1 个循环之后,它应该循环 4 次)。

就像@Variable 在第一个循环完成后重置为默认值 (0) 而不是保持原始值 (4)。

我该如何解决这个问题?

【问题讨论】:

  • 为该变量赋值的还有什么?贴一张你的画布的照片。你的逻辑应该是有效的。
  • 您的 EvalAssignment 逻辑倒退。 Reference implementation
  • 除了这个 SQL 代码 (SELECT COUNT(*)/100000+1 as Variable FROM ODS.dbo.F_AIRQ_BULK_DUMP) 工作正常,我使用脚本文本框将变量值显示为测试它是 4。在第一个循环完成后,变量变为默认值,我输入为 0。@billinkc 为什么它向后,这是一个数学公式,不管它走哪条路都长因为布尔值是正确的方法。
  • 在放入脚本任务后,在 For 循环中的每个步骤后向我显示变量值后,我能够确定变量在运行执行流程任务后立即重置为 0。该任务与@Variable 无关。
  • 看起来@Variable 值被替换为执行流程任务的退出代码,而不是变量的默认值。如果我中断执行流程任务,变量将获得值 -1073741510。 LOL 莫名其妙

标签: visual-studio-2010 variables for-loop ssis


【解决方案1】:

更有可能的是:使用名称 Variable(SSIS 为新变量默认使用的名称)与 SSIS 包中的任何东西不兼容,或者您​​做了一些您没有做过的事情显示了吗?

我创建了一个包含两个变量的包,VariableStart。我从一个值为 4 的 SQL 查询中填充了 Variable,然后按照描述使用了 For 循环,我没有遇到提前终止的情况。

我的包,设计时值设置为零的变量。

我的 For 循环容器

循环的最后一次迭代

可重复的结果

商业智能标记语言 Biml 描述了商业智能平台。在这里,我们将使用它来描述 ETL。 BIDS Helper,是 Visual Studio/BIDS/SSDT 的免费插件,解决了它的许多缺点。

您需要编辑第 3 行,使其成为您机器的有效 OLE DB 连接管理器(指向 SQL Server 安装并可能更新提供程序)

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2012;Initial Catalog=tempdb;Provider=SQLNCLI11;Integrated Security=SSPI;" />
    </Connections>
    <Packages>
        <Package Name="so_25878932" ConstraintMode="Linear">
            <Variables>
                <Variable Name="Variable" DataType="Int32">0</Variable>
                <Variable Name="Start" DataType="Int32">0</Variable>
            </Variables>
            <Tasks>
                <ExecuteSQL ConnectionName="CM_OLE" Name="SQL Variable" ResultSet="SingleRow">
                    <DirectInput>SELECT 4 AS Variable;</DirectInput>
                    <Results>
                        <Result Name="0" VariableName="User.Variable"/>
                    </Results>
                </ExecuteSQL>
                <ForLoop ConstraintMode="Linear" Name="FLC Go">
                    <InitializerExpression>@Start = 1</InitializerExpression>
                    <LoopTestExpression>@Variable >= @Start</LoopTestExpression>
                    <CountingExpression>@Start = @Start + 1</CountingExpression>
                    <Tasks>
                        <!--
                        Pilfered from http://bimlscript.com/Snippet/Details/74
                        -->
                        <Script 
                            ProjectCoreName="ST_232fecafb70a4e8a904cc21f8870eed0" 
                            Name="SCR Emit Variable and Start">
                            <ReadOnlyVariables>
                                <ReadOnlyVariable VariableName="User.Variable" />
                                <ReadOnlyVariable VariableName="User.Start" />
                            </ReadOnlyVariables>
                            <ScriptTaskProject>
                                <ScriptTaskProject ProjectCoreName="ST_c41ad4bf47544c49ad46f4440163feae" Name="TaskScriptProject1">
                                    <AssemblyReferences>
                                        <AssemblyReference AssemblyPath="Microsoft.SqlServer.ManagedDTS.dll" />
                                        <AssemblyReference AssemblyPath="Microsoft.SqlServer.ScriptTask.dll" />
                                        <AssemblyReference AssemblyPath="System.dll" />
                                        <AssemblyReference AssemblyPath="System.AddIn.dll" />
                                        <AssemblyReference AssemblyPath="System.Data.dll" />
                                        <AssemblyReference AssemblyPath="System.Windows.Forms.dll" />
                                        <AssemblyReference AssemblyPath="System.Xml.dll" />
                                    </AssemblyReferences>
                                    <Files>
                                        <File Path="AssemblyInfo.cs">
                                            using System.Reflection;
                                            using System.Runtime.CompilerServices;

                                            //
                                            // General Information about an assembly is controlled through the following
                                            // set of attributes. Change these attribute values to modify the information
                                            // associated with an assembly.
                                            //
                                            [assembly: AssemblyTitle("ST_c41ad4bf47544c49ad46f4440163feae.csproj")]
                                            [assembly: AssemblyDescription("")]
                                            [assembly: AssemblyConfiguration("")]
                                            [assembly: AssemblyCompany("Varigence")]
                                            [assembly: AssemblyProduct("ST_c41ad4bf47544c49ad46f4440163feae.csproj")]
                                            [assembly: AssemblyCopyright("Copyright @ Varigence 2013")]
                                            [assembly: AssemblyTrademark("")]
                                            [assembly: AssemblyCulture("")]
                                            [assembly: AssemblyVersion("1.0.*")]
                                        </File>
                                        <File Path="ScriptMain.cs">
                                            using System;
                                            using System.Data;
                                            using Microsoft.SqlServer.Dts.Runtime;
                                            using System.Windows.Forms;

                                            // if SSIS2012, use the following line:
                                            [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]

                                            // if earlier version, use the next line instead of the above line:
                                            // [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
                                            public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
                                            {
                                            enum ScriptResults
                                            {
                                            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
                                            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
                                            };

                                            public void Main()
                                            {
                                            int i = 0;
                                            MessageBox.Show(string.Format("{0}:{1}", Dts.Variables[i].Name, Dts.Variables[i].Value));
                                            i++;
                                            MessageBox.Show(string.Format("{0}:{1}", Dts.Variables[i].Name, Dts.Variables[i].Value));
                                            Dts.TaskResult = (int)ScriptResults.Success;
                                            }
                                            }
                                        </File>
                                    </Files>
                                </ScriptTaskProject>
                            </ScriptTaskProject>
                        </Script>
                        <ExecuteProcess Executable="cmd.exe" Name="EP Do nothing" Arguments="/C">

                        </ExecuteProcess>
                    </Tasks>
                </ForLoop>
            </Tasks>
        </Package>
    </Packages>
</Biml>

根本原因猜测

可以在包内的不同范围内创建变量。我假设由于使用默认名称 Variable 两个或更多创建了一个变量,因此这些变量以相同的名称存在但在不同的应用程序范围内。因此,如果我在我的 ForLoop 容器上定义了第二个名为 Variable 的 SSIS 变量,除非另有定义,否则它将以值 0 开始。我的包执行将开始,将值 4 分配给我的包级别 Variable。控制切换到我的 ForLoop 容器。从范围界定的角度来看,那里定义的Variable 获胜,所以我的值为0,而不是4,因为没有任何东西对其进行初始化。在这种情况下,ForLoop 永远不会触发,因为已经满足了终端条件。对于您的情况,我进一步假设有人将该变量初始化为 1。

注意这里的范围,我认为这是您的根本原因。

【讨论】:

    【解决方案2】:

    解决方案:

    请勿将 SSIS 变量命名为 @Variable。这样做会无意中导致变量值在运行时获取包中其他进程的退出代码。

    在我的情况下,@Variable 值将在成功运行退出代码为 0 的执行流程任务后自动更改为 0;或当该进程运行失败时更改为 -1073741510。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 2018-10-11
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      相关资源
      最近更新 更多