如何在biml中访问Package Variables Collection?

时间:2016-08-12 01:26:56

标签: ssis biml

我刚刚开始使用biml和bimlscript。我可以看到它拥有的强大功能,但到目前为止,通过语言和API参考挖掘令人沮丧。我似乎无法在线找到任何参考资料来访问软件包的变量集合。

我正在尝试设置此脚本,以便我可以在“变量”部分中添加更多变量,然后在此过程的后期自动将这些变量添加到脚本任务中。

以下是我的问题的最小代码:

<Biml xmlns="http://schemas.varigence.com/biml.xsd" >
  <Packages>
    <Package Name="Load">
      <Variables>
        <Variable Name="ETLProcessStepID" DataType="Int32">0</Variable>
        <Variable Name="TenantID" DataType="Int32">1</Variable>
      </Variables>
      <!-- more stuff going on in the biml -->
       <# var package = RootNode.Packages.Where(loadPackage => loadPackage.Name.Contains("Load")); 
          foreach (var variable in package.Variables) { #>
            <ReadWriteVariables VariableName="<#=variable.Name#>" />   
       <# }#>
    </Package>
  </Packages>
</Biml>

这似乎是我最接近的。不幸的是,结果是:

Error   0   'System.Collections.Generic.IEnumerable<Varigence.Languages.Biml.Task.AstPackageNode>' does not contain a definition for 'Variables' and no extension method 'Variables' accepting a first argument of type 'System.Collections.Generic.IEnumerable<Varigence.Languages.Biml.Task.AstPackageNode>' could be found (are you missing a using directive or an assembly reference?).

如果我正确阅读文档,则Packages节点中有一个Variables集合。 https://varigence.com/Documentation/Api/Type/AstPackageNode

如果我没有正确阅读文档,是否有人可以指导我如何访问包变量集合?

1 个答案:

答案 0 :(得分:1)

您遇到的第一个错误是您的C#变量称为package将从该Linq调用返回一个集合。由于只应该有一个匹配它的元素,我们将使用First给我们一个这样的东西

var package = RootNode.Packages.Where(loadPackage => loadPackage.Name.Contains("Load")).First();

现在是棘手的部分,我实际上必须检查一些更大的枪,但我不认为你能够访问当前包的变量集合,因为它还没有建立。好吧,至少使用BIDS Helper / BimlExpress。 Biml首先需要编译成对象,因为假设单个选择,RootNode.Packages集合中将没有任何内容。你肯定不会“加载”,因为你现在正在编译它。

在Mist中,付费解决方案很快将更名为BimlStudio,您可以使用Transformer来实现这一目标。您首先构建Load包,然后在发射之前将变换器作为dtsx包启动,并执行您正在尝试的任何更正。

考虑以下测试工具。它创建一个简单的包,然后在它之后立即有一些bimlscript,其中我枚举所有包,然后对于每个包,我枚举根级别Variables集合。您只会看到呈现的“测试”消息。内部调用不会触发,因为还没有存在。

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
        <Package Name="so_38908470" >
            <Variables>
                <Variable Name="ETLProcessStepID" DataType="Int32">0</Variable>
                <Variable Name="TenantID" DataType="Int32">1</Variable>
            </Variables>
    <#

    string message = "<!-- {0} -->";
    WriteLine(message, "test");
    foreach (var package in RootNode.Packages)
    {
        WriteLine(message, package.Name);
        foreach(var variable in package.Variables)
        {
            WriteLine(message, variable.Name);
        }
    }
    #>
        </Package>
    </Packages>
</Biml>

我越是想到这一点,Tiering可以通过BIDS Helper / BimlExpress实现这一目标。因为看起来您正在尝试使用包中定义的变量作为脚本任务或组件的输入,只要您使用ScriptProjects键入与Packages集合并行的内容,这可能会起作用。

尤里卡

将两个Biml文件添加到项目中:Load.biml和Script.Biml。在每个中使用以下代码。选择两者并右键单击以生成SSIS包。

Load.biml

这将是你的包裹。这是你在上面启动的包中有一个Script Task,它将转储在包的根目录中声明的所有用户变量的名称和值。但是正如您所看到的,ScriptTask标记中没有任何内容指定了哪些变量或代码将要执行的操作。

<Biml xmlns="http://schemas.varigence.com/biml.xsd" >
  <Packages>
    <Package Name="Load">
      <Variables>
        <Variable Name="ETLProcessStepID" DataType="Int32">0</Variable>
        <Variable Name="TenantID" DataType="Int32">1</Variable>
      </Variables>
            <Tasks>
                <Script ProjectCoreName="ST_EchoBack" Name="SCR Echo Back">
                    <ScriptTaskProjectReference ScriptTaskProjectName="ST_EchoBack" />
                </Script>            
            </Tasks>
    </Package>
  </Packages>
</Biml>

Script.biml

这个biml看起来很多,但它与我上面使用的概念相同,我通过包集合枚举,然后使用Variables集合。我使用biml块来控制NamespaceNameDataType属性的发射。

<#@ template language="C#" tier="1" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd" >
<ScriptProjects>
        <ScriptTaskProject ProjectCoreName="ST_EchoBack" Name="ST_EchoBack" VstaMajorVersion="0">
            <ReadOnlyVariables>
                <!-- List all the variables you are interested in tracking -->
    <#
    string message = "<!-- {0} -->";
    WriteLine(message, "test");
//    ValidationReporter.Report(Severity.Error, "test");

    foreach (var package in RootNode.Packages.Where(x=> x.Name == "Load"))
    {
        WriteLine(message, package.Name);
//        ValidationReporter.Report(Severity.Error, package.Name);
        foreach(var variable in package.Variables)
        {
            WriteLine(message, variable.Name);
//            ValidationReporter.Report(Severity.Error, variable.Name);
            #>
            <Variable Namespace="<#=variable.Namespace#>" VariableName="<#=variable.Name#>" DataType="<#=variable.DataType#>" />
            <#
        }
    }
    #>
            </ReadOnlyVariables>
            <Files>
                <File Path="ScriptMain.cs" BuildAction="Compile">using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;

namespace ST_EchoBack
{
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {
        public void Main()
        {
            bool fireAgain = false;
            string message = "{0}::{1} : {2}";
            foreach (var item in Dts.Variables)
            {
                Dts.Events.FireInformation(0, "SCR Echo Back", string.Format(message, item.Namespace, item.Name, item.Value), string.Empty, 0, ref fireAgain);
            }

            Dts.TaskResult = (int)ScriptResults.Success;
        }

        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
    }
}                </File>
                <File Path="Properties\AssemblyInfo.cs" BuildAction="Compile">
using System.Reflection;
using System.Runtime.CompilerServices;

[assembly: AssemblyVersion("1.0.*")]
                </File>
            </Files>
            <AssemblyReferences>
                <AssemblyReference AssemblyPath="System" />
                <AssemblyReference AssemblyPath="System.Data" />
                <AssemblyReference AssemblyPath="System.Windows.Forms" />
                <AssemblyReference AssemblyPath="System.Xml" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.ManagedDTS.dll" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.ScriptTask.dll" />
            </AssemblyReferences>
        </ScriptTaskProject>
    </ScriptProjects>        
</Biml>

我认为我可以简化调用GetBiml()变量variable,但这会发出完全 biml,它是用

定义的
<Variable Name="ETLProcessStepID" DataType="Int32">0</Variable>
<Variable Name="TenantID" DataType="Int32">1</Variable>

如果那里没有实际值,那么它就是ReadOnly / ReadWrite变量集合的合法语法。 Quelástima。