在脚本转换中对多个输入列应用行转换,并在列上循环,而不需要列名称

问题描述 投票:0回答:2

我正在尝试在 SSIS 中导入一个包含合并单元格的 Excel 文件,并且 SSIS 将这些合并单元格读取为 NULL,而不是第一个包含数据的单元格。

我正在尝试解析信息,为此我想将合并的单元格数据应用到之前合并的每个单元格。

我发现这段代码将代码应用于 F1 列(在我的输入中)

    // This script adjusts the value of all string fields
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]

public class ScriptMain : UserComponent
{
    string filledField1 = "";

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        // Check if the value is null
        if (Row.F1_IsNull)
        {
            // If null => replace value by variable
            Row.F1 = filledField1;
        }
        else
        {
            // If not null => replace variable by value
            filledField1 = Row.F1;
        }
    }
}

我想要的是通过 foreach 循环将此代码应用于多个列,但只有在我之前知道列的名称时才能做到这一点。

如何转换此代码以将转换应用于每列的每一行,而不是仅应用于 F1 列?

c# loops import ssis
2个回答
2
投票

你将无法概括它。如果有人不知道,我很乐意删除此内容并奖励他们的答案。

为什么不能这样做是因为在您的

Input0_ProcessInputRow
方法中,在
ScriptMain
类中,接受
Input0Buffer
作为参数。 Input0Buffer 是一个自动生成的类。以下注释位于
BufferWrapper.cs
文件的开头,该文件定义了 Input0Buffer 类

/* THIS IS AUTO-GENERATED CODE THAT WILL BE OVERWRITTEN! DO NOT EDIT!
*  Microsoft SQL Server Integration Services buffer wrappers
*  This module defines classes for accessing data flow buffers
*  THIS IS AUTO-GENERATED CODE THAT WILL BE OVERWRITTEN! DO NOT EDIT! */

因此,该类定义了 ProcessInputMethod 中可用的内容。它会为您在单击“编辑脚本”按钮之前选择的所有列生成一堆 getter 和/或 setter 方法以及 IsNull 方法。

Input0Buffer 派生自 ScriptBuffer 类。 ScriptBuffer 的定义如下

namespace Microsoft.SqlServer.Dts.Pipeline { public class ScriptBuffer { protected PipelineBuffer Buffer; protected int[] BufferColumnIndexes; public ScriptBuffer(PipelineBuffer BufferToUse, int[] BufferColumnIndexesToUse, OutputNameMap OutputMap); protected object this[int ColumnIndex] { get; set; } protected void AddRow(); protected void DirectRow(string outputName); protected bool EndOfRowset(); protected bool IsNull(int ColumnIndex); protected bool NextRow(); protected void SetEndOfRowset(); protected void SetNull(int ColumnIndex); } }

需要注意的是,名为 Buffer 的

PipelineBuffer

 实例在 ScriptBuffer 类中被定义为受保护的。它在我们的自动生成的类中没有定义为任何内容,因此在该类定义之外无法访问它。这意味着当我们“使用”实例时,就像我们在 ScriptMain 中所做的那样,我们无法触摸受保护的成员,因为它们的行为就像私有的一样。 
我确信您可以实现 IEnumerable 接口,这样您就可以在 Input0Buffer 类上执行您想要执行的操作,但要知道每次您打开脚本时,Visual Studio 都会重新生成该类并删除您的编辑.

当我输入此内容时,我正在做笔记以检查

扩展方法

如何提供一种方法...

事实上,您实际上

2
投票
访问脚本中的底层对象并迭代缓冲区,而无需使用命名列。您需要继承缓冲区并在

public override void ProcessInput(int InputID, string InputName, PipelineBuffer Buffer, OutputNameMap OutputMap)中使用这个继承的类。我通常使用从 Input0Buffer 继承的类(自动生成的类),这样我就可以访问 both

 命名列和可迭代列。您可以使用 
Reflection 获取列的索引 例如:
using System.Reflection;
...    
#region Input0ByIndexBuffer
//inherit via BufferWrapper 
    public class Input0ByIndexBuffer : Input0Buffer
    {
        public Dictionary<string, int> ColumnIndexes = new Dictionary<string, int>();

        public Input0ByIndexBuffer(PipelineBuffer Buffer, int[] BufferColumnIndexes, OutputNameMap OutputMap) : base(Buffer, BufferColumnIndexes, OutputMap)
        {
            IList<string> propertyList = new List<string>();
            foreach (PropertyInfo property in typeof(Input0Buffer).GetProperties())
                if (!property.Name.EndsWith("_IsNull"))
                    propertyList.Add(property.Name.ToUpperInvariant());
            for (int i = 0; i < propertyList.Count; i++)
                ColumnIndexes[propertyList[i]] = i;
        }
        new public bool IsNull(int columnIndex)
        {
            return base.IsNull(columnIndex);
        }
        new public void SetNull(int columnIndex)
        {
            base.SetNull(columnIndex);
        }
        new public object this[int ColumnIndex]
        {
            get
            {
                return base[ColumnIndex];
                // return GetObject(ColumnIndex);
            }
            set
            {
                //SetObject(ColumnIndex, value, false);
                base[ColumnIndex] = value;
            }
        }
        public BufferColumn GetColumnInfo(int columnIndex)
        {
            return Buffer.GetColumnInfo(BufferColumnIndexes[columnIndex]);
        }
        //expose the Buffer.Get methods using the columnindex, this enables iterations over index instead of columns names
        public object GetObject(int columnIndex)
        {
            BufferColumn columnInfo = GetColumnInfo(columnIndex);
            switch (columnInfo.DataType)
            {
                case DataType.DT_BOOL:
                case DataType.DT_BYREF_BOOL:
                    return GetBoolean(columnIndex);
                case DataType.DT_I2:
                case DataType.DT_BYREF_I2:
                    return GetInt16(columnIndex);
                case DataType.DT_I4:
                case DataType.DT_BYREF_I4:
                    return GetInt32(columnIndex);
                case DataType.DT_R4:
                case DataType.DT_BYREF_R4:
                    return GetSingle(columnIndex);
                case DataType.DT_R8:
                case DataType.DT_BYREF_R8:
                    return GetDouble(columnIndex);
                case DataType.DT_CY:
                case DataType.DT_BYREF_CY:
                case DataType.DT_DECIMAL:
                case DataType.DT_NUMERIC:
                case DataType.DT_BYREF_DECIMAL:
                case DataType.DT_BYREF_NUMERIC:
                    return GetDecimal(columnIndex);
                case DataType.DT_I1:
                case DataType.DT_BYREF_I1:
                    return GetSByte(columnIndex);
                case DataType.DT_UI1:
                case DataType.DT_BYREF_UI1:
                    return GetByte(columnIndex);
                case DataType.DT_UI2:
                case DataType.DT_BYREF_UI2:
                    return GetUInt16(columnIndex);
                case DataType.DT_UI4:
                case DataType.DT_BYREF_UI4:
                    return GetUInt32(columnIndex);
                case DataType.DT_I8:
                case DataType.DT_BYREF_I8:
                    return GetInt64(columnIndex);
                case DataType.DT_UI8:
                case DataType.DT_BYREF_UI8:
                    return GetUInt64(columnIndex);
                case DataType.DT_DBDATE:
                case DataType.DT_BYREF_DBDATE:
                    return GetDate(columnIndex);
                case DataType.DT_DATE:
                case DataType.DT_BYREF_DATE:
                case DataType.DT_FILETIME:
                case DataType.DT_BYREF_FILETIME:
                case DataType.DT_DBTIME:
                case DataType.DT_BYREF_DBTIME:
                case DataType.DT_DBTIMESTAMP:
                case DataType.DT_BYREF_DBTIMESTAMP:
                case DataType.DT_DBTIME2:
                case DataType.DT_BYREF_DBTIME2:
                case DataType.DT_DBTIMESTAMPOFFSET:
                case DataType.DT_BYREF_DBTIMESTAMPOFFSET:
                case DataType.DT_DBTIMESTAMP2:
                case DataType.DT_BYREF_DBTIMESTAMP2:
                    return GetDateTime(columnIndex);
                default:
                    throw new Exception(columnInfo.DataType.ToString() + " not yet supported ");
            }
        }
        public void SetObject(int columnIndex, object value, bool failSilently = true)
        {
            BufferColumn columnInfo = GetColumnInfo(columnIndex);
            try
            {
                switch (columnInfo.DataType)
                {
                    case DataType.DT_BOOL:
                    case DataType.DT_BYREF_BOOL:
                        SetBoolean(columnIndex, (bool)value);
                        break;
                    case DataType.DT_I2:
                    case DataType.DT_BYREF_I2:
                        SetInt16(columnIndex, (short)value);
                        break;
                    case DataType.DT_I4:
                    case DataType.DT_BYREF_I4:
                        SetInt32(columnIndex, (int)value);
                        break;
                    case DataType.DT_R4:
                    case DataType.DT_BYREF_R4:
                        SetSingle(columnIndex, (float)value);
                        break;
                    case DataType.DT_R8:
                    case DataType.DT_BYREF_R8:
                        SetDouble(columnIndex, (double)value);
                        break;
                    case DataType.DT_CY:
                    case DataType.DT_BYREF_CY:
                    case DataType.DT_DECIMAL:
                    case DataType.DT_NUMERIC:
                    case DataType.DT_BYREF_DECIMAL:
                    case DataType.DT_BYREF_NUMERIC:
                        SetDecimal(columnIndex, (decimal)value);
                        break;
                    case DataType.DT_I1:
                    case DataType.DT_BYREF_I1:
                        SetSByte(columnIndex, (sbyte)value);
                        break;
                    case DataType.DT_UI1:
                    case DataType.DT_BYREF_UI1:
                        SetByte(columnIndex, (byte)value);
                        break;
                    case DataType.DT_UI2:
                    case DataType.DT_BYREF_UI2:
                        SetUInt16(columnIndex, (ushort)value);
                        break;
                    case DataType.DT_UI4:
                    case DataType.DT_BYREF_UI4:
                        SetUInt32(columnIndex, (uint)value);
                        break;
                    case DataType.DT_I8:
                    case DataType.DT_BYREF_I8:
                        SetInt64(columnIndex, (long)value);
                        break;
                    case DataType.DT_UI8:
                    case DataType.DT_BYREF_UI8:
                        SetUInt64(columnIndex, (ulong)value);
                        break;
                    case DataType.DT_DBDATE:
                    case DataType.DT_BYREF_DBDATE:
                        SetDate(columnIndex, (DateTime)value);
                        break;
                    case DataType.DT_DATE:
                    case DataType.DT_BYREF_DATE:
                    case DataType.DT_FILETIME:
                    case DataType.DT_BYREF_FILETIME:
                    case DataType.DT_DBTIME:
                    case DataType.DT_BYREF_DBTIME:
                    case DataType.DT_DBTIMESTAMP:
                    case DataType.DT_BYREF_DBTIMESTAMP:
                    case DataType.DT_DBTIME2:
                    case DataType.DT_BYREF_DBTIME2:
                    case DataType.DT_DBTIMESTAMPOFFSET:
                    case DataType.DT_BYREF_DBTIMESTAMPOFFSET:
                    case DataType.DT_DBTIMESTAMP2:
                    case DataType.DT_BYREF_DBTIMESTAMP2:
                        SetDateTime(columnIndex, (DateTime)value);
                        break;
                    default:
                        throw new Exception(columnInfo.DataType.ToString() + " not yet supported ");
                }
            }
            catch (Exception e)
            {
                if (failSilently == false)
                    throw e;
                else
                    try { SetNull(columnIndex); } catch { }
            }
        }
        public sbyte GetSByte(int columnIndex)
        {
            return Buffer.GetSByte(BufferColumnIndexes[columnIndex]);
        }
        public byte GetByte(int columnIndex)
        {
            return Buffer.GetByte(BufferColumnIndexes[columnIndex]);
        }
        public bool GetBoolean(int columnIndex)
        {
            return Buffer.GetBoolean(BufferColumnIndexes[columnIndex]);
        }
        public short GetInt16(int columnIndex)
        {
            return Buffer.GetInt16(BufferColumnIndexes[columnIndex]);
        }
        public ushort GetUInt16(int columnIndex)
        {
            return Buffer.GetUInt16(BufferColumnIndexes[columnIndex]);
        }
        public int GetInt32(int columnIndex)
        {
            return Buffer.GetInt32(BufferColumnIndexes[columnIndex]);
        }
        public uint GetUInt32(int columnIndex)
        {
            return Buffer.GetUInt32(BufferColumnIndexes[columnIndex]);
        }
        public long GetInt64(int columnIndex)
        {
            return Buffer.GetInt64(BufferColumnIndexes[columnIndex]);
        }
        public ulong GetUInt64(int columnIndex)
        {
            return Buffer.GetUInt64(BufferColumnIndexes[columnIndex]);
        }
        public decimal GetDecimal(int columnIndex)
        {
            return Buffer.GetDecimal(BufferColumnIndexes[columnIndex]);
        }
        public float GetSingle(int columnIndex)
        {
            return Buffer.GetSingle(BufferColumnIndexes[columnIndex]);
        }
        public double GetDouble(int columnIndex)
        {
            return Buffer.GetDouble(BufferColumnIndexes[columnIndex]);
        }
        public DateTime GetDateTime(int columnIndex)
        {
            return Buffer.GetDateTime(BufferColumnIndexes[columnIndex]);
        }
        public DateTime GetDate(int columnIndex)
        {
            return Buffer.GetDate(BufferColumnIndexes[columnIndex]);
        }
        public byte[] GetBytes(int columnIndex)
        {
            return Buffer.GetBytes(BufferColumnIndexes[columnIndex]);
        }
        public DateTimeOffset GetDateTimeOffset(int columnIndex)
        {
            return Buffer.GetDateTimeOffset(BufferColumnIndexes[columnIndex]);
        }
        public Guid GetGuid(int columnIndex)
        {
            return Buffer.GetGuid(BufferColumnIndexes[columnIndex]);
        }
        public string GetString(int columnIndex)
        {
            return Buffer.GetString(BufferColumnIndexes[columnIndex]);
        }
        public TimeSpan GetTime(int columnIndex)
        {
            return Buffer.GetTime(BufferColumnIndexes[columnIndex]);
        }

        //to test against componentwrapper?
        public uint GetBlobLength(int columnIndex)
        {
            return Buffer.GetBlobLength(BufferColumnIndexes[columnIndex]);
        }
        public byte[] GetBlobData(int columnIndex, int offset, int count)
        {
            return Buffer.GetBlobData(BufferColumnIndexes[columnIndex], offset, count);
        }



        public void AddBlobData(int columnIndex, byte[] data)
        {
            Buffer.AddBlobData(BufferColumnIndexes[columnIndex], data);
        }
        public void AddBlobData(int columnIndex, byte[] data, int count)
        {
            Buffer.AddBlobData(BufferColumnIndexes[columnIndex], data, count);
        }
        public void ResetBlobData(int columnIndex)
        {
            Buffer.ResetBlobData(columnIndex);
        }
        public void SetBoolean(int columnIndex, bool value)
        {
            Buffer.SetBoolean(BufferColumnIndexes[columnIndex], value);
        }
        public void SetByte(int columnIndex, byte value)
        {
            Buffer.SetByte(BufferColumnIndexes[columnIndex], value);
        }
        public void SetBytes(int columnIndex, byte[] bytesValue)
        {
            Buffer.SetBytes(BufferColumnIndexes[columnIndex], bytesValue);
        }
        public void SetDate(int columnIndex, DateTime value)
        {
            Buffer.SetDate(BufferColumnIndexes[columnIndex], value);
        }
        public void SetDateTime(int columnIndex, DateTime value)
        {
            Buffer.SetDateTime(BufferColumnIndexes[columnIndex], value);
        }
        public void SetDateTimeOffset(int columnIndex, DateTimeOffset value)
        {
            Buffer.SetDateTimeOffset(BufferColumnIndexes[columnIndex], value);
        }
        public void SetDecimal(int columnIndex, decimal value)
        {
            Buffer.SetDecimal(BufferColumnIndexes[columnIndex], value);
        }
        public void SetDouble(int columnIndex, double value)
        {
            Buffer.SetDouble(BufferColumnIndexes[columnIndex], value);
        }
        public void SetGuid(int columnIndex, Guid value)
        {
            Buffer.SetGuid(BufferColumnIndexes[columnIndex], value);
        }
        public void SetInt16(int columnIndex, short value)
        {
            Buffer.SetInt16(BufferColumnIndexes[columnIndex], value);
        }
        public void SetInt32(int columnIndex, int value)
        {
            Buffer.SetInt32(BufferColumnIndexes[columnIndex], value);
        }
        public void SetInt64(int columnIndex, long value)
        {
            Buffer.SetInt64(BufferColumnIndexes[columnIndex], value);
        }
        public void SetSByte(int columnIndex, sbyte value)
        {
            Buffer.SetSByte(BufferColumnIndexes[columnIndex], value);
        }
        public void SetSingle(int columnIndex, float value)
        {
            Buffer.SetSingle(BufferColumnIndexes[columnIndex], value);
        }
        public void SetString(int columnIndex, string value)
        {
            Buffer.SetString(BufferColumnIndexes[columnIndex], value);
        }
        public void SetTime(int columnIndex, TimeSpan value)
        {
            Buffer.SetTime(BufferColumnIndexes[columnIndex], value);
        }
        public void SetUInt16(int columnIndex, ushort value)
        {
            Buffer.SetUInt16(BufferColumnIndexes[columnIndex], value);
        }
        public void SetUInt32(int columnIndex, uint value)
        {
            Buffer.SetUInt32(BufferColumnIndexes[columnIndex], value);
        }
        public void SetUInt64(int columnIndex, ulong value)
        {
            Buffer.SetUInt64(BufferColumnIndexes[columnIndex], value);
        }
    }
#endregion

并将其用于:
public void Input0_ProcessInputRow(Input0ByIndexBuffer Row)
{
    //do your code
}
public override void ProcessInput(int InputID, string InputName, PipelineBuffer Buffer, OutputNameMap OutputMap)
{
    if (InputName.Equals(@"Input 0", StringComparison.Ordinal))
    {
        Input0_ProcessInput(new Input0ByIndexBuffer(Buffer, GetColumnIndexes(InputID), OutputMap));
    }

}

public  void Input0_ProcessInput(Input0ByIndexBuffer Buffer)
{
    while (Buffer.NextRow())
    {
        Input0_ProcessInputRow(Buffer);
    }
}

我将从字典中获得的列名称的实际索引
ColumnIndexes

(字典从

typeof(Input0Buffer).GetProperties()

获取其列名称)

作品:

© www.soinside.com 2019 - 2024. All rights reserved.