【问题标题】:How can I use Contains() to evaluate InputBuffer rows when using SSIS Script Transform?使用 SSIS 脚本转换时如何使用 Contains() 评估 InputBuffer 行?
【发布时间】:2015-07-10 01:10:27
【问题描述】:

我正在学习使用 SSIS 2012 脚本组件 (C#) 根据可能条件列表转换值。

我已成功使用 == 运算符将输入行与 switch 块中的确切字符串值进行比较,但是当我在 if-else 块中尝试 .Contains() 方法时,所有行作为 case else 返回。

我在下面显示了两种代码尝试。我正在使用 .Contains() 方法并使用MSDN 进行了仔细检查。在我看来,我使用的方法是正确的。

为什么我可以进行精确的 == 运算符评估但不能进行 .Contains() 评估?

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    // This block does **not** succeed in evaluating the Row.MealCode value 
    // with the .Contains("string") method. All rows evaluate as case else.

    if (Row.MealCode.Contains("FREE"))
    {
        Row.tMealCode = "Free";
    }
    else
    {
        Row.tMealCode = "Else";
    }


    // This code successfully evaluates the value of MealCode 
    // in each row and correctly outputs it as a tMealCode value.

    switch (Row.MealCode)
    {   
        case "Free lunch":                
        case "FREE":
            Row.tMealCode = "Free";
            break;
        case "Reduced Lunch":
        case "RED":
            Row.tMealCode = "Reduced";
            break;
        case "REG":
            Row.tMealCode = "Regular";
            break;
        default:
            Row.tMealCode = "Else";
            break;
    }
}

为了提供更多上下文,此屏幕截图显示了我在 OLE DB 目标 任务之前放置脚本组件的位置。

【问题讨论】:

    标签: c# ssis


    【解决方案1】:

    来自引用的 MSDN

    返回一个值,指示指定的子字符串是否出现在此字符串中。

    假设您的源数据包含以下值

    • 免费
    • 免费
    • 免费
    • 免费
    • 免费

    .Contains("FREE") 只会匹配第一个值,因为它会进行区分大小写的比较。

    您在 switch 语句中做了很多相同的事情 - 您已经针对遇到的各种外壳进行了编码。

    您需要进行不区分大小写的比较 How can I do a case insensitive string comparison?

    或者,如果您打算使用 Contains 方法,请确保两个参数的大小写正确。

    if (Row.MealCode.ToUpper().Contains("FREE".ToUpper()))
    

    比米尔

    商业智能标记语言 Biml 是商业智能的平台。在这里,我们将使用它来描述 ETL。 BIDS Helper,是 Visual Studio/BIDS/SSDT 的免费插件,可改善开发体验。具体来说,我们将使用将描述 ETL 的 Biml 文件转换为 SSIS 包的能力。这样做的另一个好处是为您提供了一种机制,可以准确地生成我所描述的解决方案,而不是单击许多繁琐的对话框。

    安装后,将新的 Biml 文件添加到您的 SSIS 项目并编辑第 5 行以指向有效的 SQL Server 实例。右键单击 biml 文件并选择 Generate SSIS Package。

    以下是使用 Contains 生成具有预期逻辑的 SSIS 包所需的 Biml 示例

    <Biml xmlns="http://schemas.varigence.com/biml.xsd">
      <Connections>
        <Connection
            Name="tempdb"
            ConnectionString="Data Source=.\dev2008;Initial Catalog=tempdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;"
                />
      </Connections>
      <Packages>
        <Package Name="so_31330881">
          <Tasks>
            <Dataflow Name="DFT Sample">
              <Transformations>
                <OleDbSource ConnectionName="tempdb" Name="OLESRC dbo_Source">
                  <DirectInput>SELECT D.MealCode FROM (VALUES ('FREE'), ('free'), ('Free')) AS D(MealCode);</DirectInput>
                </OleDbSource>
                <ScriptComponentTransformation ProjectCoreName="SC_31330881" Name="SCR Transform values">
                  <ScriptComponentProjectReference ScriptComponentProjectName="SC_31330881" />
                </ScriptComponentTransformation>
                <DerivedColumns Name="DER Placeholder" />
              </Transformations>
            </Dataflow>
          </Tasks>
        </Package>
      </Packages>
    
        <ScriptProjects>
            <ScriptComponentProject ProjectCoreName="SC_31330881" Name="SC_31330881">
        <Files>
            <File Path="main.cs">
    using System;
    using System.Data;
    using System.Web.Services;
    using System.Text;
    using System.Xml;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
          // if (Row.MealCode.Contains("FREE"))
          if (Row.MealCode.ToUpper().Contains("FREE".ToUpper()))
          {
              Row.tMealCode = "Free";
          }
          else
          {
              Row.tMealCode = "Else";
          }      
        }
    }
    </File>
          <File Path="Properties\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("SC_31330881")]
            [assembly: AssemblyDescription("")]
            [assembly: AssemblyConfiguration("")]
            [assembly: AssemblyCompany("")]
            [assembly: AssemblyProduct("SC_31330881")]
            [assembly: AssemblyCopyright("Copyright @  2014")]
            [assembly: AssemblyTrademark("")]
            [assembly: AssemblyCulture("")]
            //
            // Version information for an assembly consists of the following four values:
            //
            //      Major Version
            //      Minor Version
            //      Build Number
            //      Revision
            //
            // You can specify all the values or you can default the Revision and Build Numbers
            // by using the '*' as shown below:
    
            [assembly: AssemblyVersion("1.0.*")]
          </File>
        </Files>
        <AssemblyReferences>
          <AssemblyReference AssemblyPath="System" />
          <AssemblyReference AssemblyPath="System.Data" />
          <AssemblyReference AssemblyPath="System.Web.Services" />
          <AssemblyReference AssemblyPath="System.Windows.Forms" />
          <AssemblyReference AssemblyPath="System.Xml" />
          <AssemblyReference AssemblyPath="Microsoft.SqlServer.TxScript.dll" />
          <AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSRuntimeWrap.dll" />
          <AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSPipelineWrap.dll" />
          <AssemblyReference AssemblyPath="Microsoft.SqlServer.PipelineHost.dll" />
        </AssemblyReferences>
              <InputBuffer Name="Input 0">
                <Columns>
                  <Column CodePage="1252" DataType="AnsiString" Length="10" Name="MealCode" UsageType="ReadOnly" />
                </Columns>
              </InputBuffer>
        <OutputBuffers>
          <OutputBuffer IsSynchronous="true" Name="Output 0">
            <Columns>
              <Column CodePage="1252" DataType="AnsiString" Length="10" Name="tMealCode" />
            </Columns>
          </OutputBuffer>
        </OutputBuffers>
      </ScriptComponentProject>
    </ScriptProjects>
    </Biml>
    

    【讨论】:

    • 这就是解决我的问题的方法。 if (Row.MealCode.ToUpper().Contains("FREE".ToUpper()))。我能够使用这种方法来设置其他 else if 语句。我不认为Contains() 区分大小写。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-24
    • 1970-01-01
    • 2012-08-10
    相关资源
    最近更新 更多