更有可能的是:使用名称 Variable(SSIS 为新变量默认使用的名称)与 SSIS 包中的任何东西不兼容,或者您做了一些您没有做过的事情显示了吗?
我创建了一个包含两个变量的包,Variable 和 Start。我从一个值为 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。
注意这里的范围,我认为这是您的根本原因。