我正在尝试在 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 列?
你将无法概括它。如果有人不知道,我很乐意删除此内容并奖励他们的答案。
为什么不能这样做是因为在您的
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 都会重新生成该类并删除您的编辑. 当我输入此内容时,我正在做笔记以检查
扩展方法
如何提供一种方法...事实上,您实际上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”中获得的列名称的实际索引: