【问题标题】:SSIS Script Component - Iterate Through Columns with NULL ValuesSSIS 脚本组件 - 遍历具有 NULL 值的列
【发布时间】:2019-12-05 10:01:01
【问题描述】:

我正在使用以下 .NET 代码遍历所有输入列以创建列的 HashByte 值,然后确定该行是否已更新。

脚本可以正常工作,直到列具有 NULL 值。如何在不使用 TRY CATCH 块的情况下编写代码?

Imports System.Text
Imports System.Reflection
Imports System.Security.Cryptography

Private sha As SHA256 = New SHA256CryptoServiceProvider() 'used To create the SHA256 hash

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

    Try

        ' create hashbyte column to identify if row has changed

        Dim concat As StringBuilder = New StringBuilder("")

        ' loop over all the input columns of the buffer row 

        For Each col As PropertyInfo In Row.GetType().GetProperties()

            If Not col.Name.ToLower.EndsWith("isnull") AndAlso Not col.Name.ToLower.Equals("hash") Then
                MsgBox(col.Name.ToLower)
                If col.GetValue(Row, Nothing) Is Nothing Then
                    concat.Append("")
                Else
                    concat.Append(Convert.ToString(col.GetValue(Row).ToString()))
                End If

                concat.Append("|")
            End If

        Next

        Dim sHashBytes As String = concat.ToString().Remove(concat.ToString().Length - 1) ' remove the last character of the string
        Dim bHashBytes As Byte() = sha.ComputeHash(System.Text.UnicodeEncoding.Unicode.GetBytes(sHashBytes))
        Dim sb As StringBuilder = New StringBuilder("")

        For i As Integer = 0 To bHashBytes.Length - 1
            sb.Append(bHashBytes(i).ToString("X2"))
        Next

        Row.Hash = "0x" & sb.ToString()

    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

谢谢,格雷格

【问题讨论】:

    标签: sql-server vb.net ssis ssis-2012 isql


    【解决方案1】:

    好吧,假设所有输入列都是 String 类型。我发布了一段代码,它将所有字符串列连接成一个字符串(在 C# 中)以进行省略计算。

    public override void ProcessInput(int InputID, PipelineBuffer Buffer)
    {
      bool fireAgain = true;
      string columnData = null;
    
      while (Buffer.NextRow())
      {
        for (int columnIndex = 0;
          columnIndex < Buffer.ColumnCount;
          columnIndex++)
        {
    
          if (!Buffer.IsNull(columnIndex))
          {
            BufferColumn columnInfo = Buffer.GetColumnInfo(columnIndex);
            switch (columnInfo.DataType)
            {
    
              // check column data type
              case DataType.DT_WSTR:
                columnData += Buffer.GetString(columnIndex);
                break;
    
              // add code to support more data types here
    
              default:
                columnData = "";
                break;
            }
          }
        }
      }
      // Do some calculations...
      base.ProcessInput(InputID, Buffer);
    }
    

    为什么调用ProcessInput 而不是Input0_ProcessInputRow 的原因 - 在后者中,所有列都具有列命名属性,因此不能循环它们。每个缓冲区都会调用此方法,因此您将拥有的模式数据(和缓冲区),您将收到的调用越多。
    调用base.ProcessInput(InputID, Buffer) 对于正确处理缓冲区、将其标记为已处理以及可用于进一步的数据流转换至关重要。

    受 Todd McDermid 的 Blog post 启发。

    【讨论】:

    • 可惜列不全是字符串,有日期和整数。
    • @Greg,您可以轻松扩展代码。例如,要处理 Int - 添加以下 case 语句 - case DataType.DT_I4: columnData += Buffer.GetInt32(columnIndex).ToString(); break; SSIS Data Types
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    相关资源
    最近更新 更多