1

我刚刚开始使用 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

如果我没有正确阅读文档,谁能指导我参考如何访问包变量集合?

4

1 回答 1

1

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

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

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

在即将更名为 BimlStudio 的付费解决方案 Mist 中,您可以使用 Transformer 来完成此任务。您首先构建负载包,然后在发射之前作为 dtsx 包启动变压器,并执行您尝试的任何校正。

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

<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 类型的东西,这可能会起作用。

尤里卡

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

加载.biml

这将是你的包裹。它是您在上面启动的包,其中包含一个脚本任务,它将转储在包根目录中声明的所有用户变量的名称和值。但是如您所见,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>

脚本.biml

这个 biml 看起来很多,但它与我在上面使用的概念相同,我枚举包集合,然后使用变量集合。我使用 biml nuggets 来控制Namespace,NameDataType属性的发射。

<#@ 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 变量集合的合法语法。阙 lástima。

于 2016-08-12T04:26:51.847 回答