首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法为SSIS中的分层生成BIML脚本

无法为SSIS中的分层生成BIML脚本
EN

Stack Overflow用户
提问于 2019-02-20 03:20:36
回答 1查看 218关注 0票数 3

我有一个情况,我的主biml生成150个执行包任务。我需要生成序列容器,以便它们中的每个容器在主包中每个序列容器都包含(150/10)15个执行包任务。

你能帮我找到一个合适的解决方案吗?欢迎任何想法/工作示例/代码库!!

代码语言:javascript
复制
<Tasks> 
    <# foreach (var package in RootNode.Packages) { #> 
         <ExecutePackage Name="Execute <#=package.Name#>" > 
              <ExternalProjectPackage Package="<#=package.PackageFileName#>" /> 
         </ExecutePackage>
    <# } #>
</Tasks> 
EN

回答 1

Stack Overflow用户

发布于 2019-02-20 06:51:43

这个答案将利用Biml的一些高级概念。第一个是分层,因此我们将在第1层中生成150个包。然后在第2层(或任何大于前一层的数字)中,我们将能够将第0层中的劳动成果引用到(tier max -1)。

第0层是静态/平面Biml (在本例中我们没有任何Biml)。由于我们将循环生成子程序包,因此它将自动位于第一层,但我选择在此明确说明,以防您有前身但又是动态的任务要解决

<#* .... #>是一个被Biml编译器忽略的超级强大的注释结构

<#+ .... #>是为将显式方法和类添加到Biml中而构建

我们还将使用Extension method将我们的包大致拆分成组,然后填充到序列容器中。

第1层

这段代码生成名称从so_54773502_000到so_54773502_149的空白SSIS包(总共150个)

代码语言:javascript
复制
<#@ template tier="1" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
<#foreach (int index in Enumerable.Range(0, 150)){#>
    <Package Name="so_54773502_<#= string.Format("{0:000}", index) #>" />
<#}#>
    </Packages>
</Biml>

第2层

在这里,我们指定需要多少个并行容器。Split方法的结果是一个列表列表。对于外部容器列表中的每个元素,我们需要添加一个序列容器。对于弹出的列表中的每个元素,我们需要枚举它并执行一个包任务。

代码语言:javascript
复制
<#@ template tier="2" #>
<#
int taskCountPerContainer = 10;
int currentContainerNumber = 0;
#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
        <Package Name="master">
            <Tasks>
<#* 
    This is such a fun bit of LINQ. I used the Split extension so handily defined on the linked question
    I pass in a List of package names and how many buckets I want and it returns a list of lists

    From there, we enumerate through the list bucket and for each element we find, we create a sequence
    container. Then, for each element in the bucket, we add an Execute Package Task.

    I was unable to Split an instance of AstPackageNodes as it resulted in the error below but the only reason
    your sample needed the full object was to provide both Name and PackageFileName properties. We can derive
    the second given the first

// foreach(var outerlist in Split(this.RootNode.Packages.ToList<AstPackageNode>(),taskCountPerContainer)){    
// results in this error. 
// Destination array was not long enough. Check destIndex and length, and the array's lower bounds.    
// TODO: Check with Varigence or run in C# project

*#>
                <#foreach(var listOfPackages in Split(this.RootNode.Packages.Select(x => x.Name).ToList<string>(), taskCountPerContainer)){#>
                <Container Name="SEQC_<#=currentContainerNumber++#>" ConstraintMode="Linear">
                    <Tasks>
                    <#foreach(var packageName in listOfPackages){#>
                        <ExecutePackage Name="EPT <#=packageName#>"><ExternalProjectPackage Package="<#=packageName#>.dtsx"/></ExecutePackage>
                    <#}#>
                    </Tasks>
                </Container>
                <#}#>
            </Tasks>
        </Package>
    </Packages>
</Biml>

<#+
// https://stackoverflow.com/questions/419019/split-list-into-sublists-with-linq
public static IList<List<T>> Split<T>(IList<T> source, int buckets)
{
    return  source
        .Select((x, i) => new { Index = i, Value = x })
        .GroupBy(x => x.Index / buckets)
        .Select(x => x.Select(v => v.Value).ToList())
        .ToList();
}

#>

最终结果

看,妈,很多包都被执行了!

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54773502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档