在SSIS(MS Visual Studio 2010)中,我创建了一个带有单行输出(int32)的SQL任务,该任务传递给User :: Variable。然后我有一个" For Loop"我希望运行的次数与SQL任务查询中的整数相等。我已经使用以下内容设置了For循环:
InitExpression: @Start = 1
EvalExpression: @Variable >= @Start
AssignExpression: @Start = @Start+1
在我的测试示例中,通过SQL任务查询将@Variable设置为4,并且循环在第一个循环中运行正常,但随后立即完成报告包成功执行(仅在1循环后应该循环4次)。
就像@Variable在完成第一个循环后重置为默认值(0)而不是保持原始值(4)。
我该如何解决这个问题?
答案 0 :(得分:1)
更有可能的是:使用SSIS默认为新变量的名称Variable
与SSIS包中的任何不兼容,或者您已经完成了某些事情没有出现?
我创建了一个包含两个变量Variable
和Start
的包。我已经从SQL查询中填充Variable
,值为4,然后按照描述使用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。
注意这里的范围,这是我认为是你的根本原因。
答案 1 :(得分:0)
解决方案:
不要将SSIS变量命名为@Variable。这样做会无意中导致变量值在运行时获取包中其他进程的退出代码。
在我的情况下,在成功运行退出代码为0的执行流程任务后,@ Variable值将自动更改为0;或当该进程运行失败时更改为-1073741510。