• 如何在SSIS的脚本组件中访问变量


    这是一个小问题,我们在SSIS的设计中很多地方都会用到变量,我习惯性地将“变量”和“表达式”称为SSIS的灵魂,虽然不见得绝对准确,但它们确实是保证一个SSIS包灵活性的根本。

    同时,我们可能也会在数据流任务中添加“脚本组件”,用我们熟知的C#或者VB.NET编写一些数据转换处理的逻辑。这里可能就有一个需求,我们希望在脚本组件中访问变量(读或者写),但默认情况下,这个需求并不是那么容易实现。我们来看下面的例子

    这个例子中,我们在Package级别定义了一个变量,名称为test

    image

    然后,我们在数据流中有一个Script Component,我们尝试在里面对上面这个变量进行读写

    image

    代码大致如下

    /* Microsoft SQL Server Integration Services Script Component
    *  Write scripts using Microsoft Visual C# 2008.
    *  ScriptMain is the entry point class of the script.*/
    
    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    using System.Windows.Forms;
    
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
    
        public override void PreExecute()
        {
            base.PreExecute();
            /*
              Add your code here for preprocessing or remove if not needed
            */
        }
    
        public override void PostExecute()
        {
            base.PostExecute();
            /*
              Add your code here for postprocessing or remove if not needed
              You can set read/write variables here, for example:
              Variables.MyIntVar = 100
            */
        }
    
        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
            /*
              Add your code here
            */
    
    
            MessageBox.Show(Variables.test.ToString());
            
            
            
        }
    
    }
    

    代码很简单,也很自然。我只是作为演示,这里读取到那个变量之后,显示出来。

    但是这个代码是不能运行的,有如下错误

    image

    上述错误的意思是,除非在PostExecute方法里面,是不可以对变量进行读写的。这里的原因是,ProcessInputRow这个方法,因为是每一行数据都会执行一次,所以如果这里随意读写变量的话,会因为要频繁加锁和解锁,造成效率方面的问题。

    这里谈到了一个加锁的问题。为什么会有这个问题呢?其实很简单,因为变量是定义在Package级别,所以很可能几个任务在同时访问这些变量,都在对其进行读写。如果不加锁,则可能导致不可预期的结果。

    如果你理解了上述机制,而且也确定可以承担锁定可能带来的性能损耗,那么要解决问题,可以通过如下的方式实现

        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
            /*
              Add your code here
            */
    
            VariableDispenser.LockForRead("User::test");//这里先声明对某个变量进行锁定
    
            IDTSVariables100 vs = null;
            this.VariableDispenser.GetVariables(out vs);//通过VariableDispenser获取变量集合
            MessageBox.Show(vs["User::test"].Value.ToString());
    
            vs.Unlock();//解锁
           
            
            
        }
  • 相关阅读:
    关于 __bridge
    关于loadView
    关于ViewDidUnload
    55. Jump Game(中等)
    54. Spiral Matrix(中等)
    48. Rotate Image(中等)
    34. Search for a Range
    18. 4Sum(中等)
    16. 3Sum Closest(中等)
    41. First Missing Positive(困难, 用到 counting sort 方法)
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/2053055.html
Copyright © 2020-2023  润新知