C# 导入具有动态列的文件
我是SSIS和C#的新手。在SQL Server 2008中,我从.csv文件导入数据。现在我有了动态列。它们可以是大约22列(有时多多少少)。我创建了一个包含25列的临时表,并将数据导入其中。实际上,我导入的每个平面文件都有不同的列数。它们的格式都是正确的。我的任务是从.csv平面文件导入所有行,包括标题。我想把它放到一个作业中,这样我就可以每天将多个文件导入到表中 所以在for-each循环中,我有一个数据流任务,其中有一个脚本组件。我(在线研究)提出了下面的C代码,但我得到了错误: 索引超出了数组的边界。 我尝试使用MessageBox查找原因,发现它正在读取第一行,索引超出了第一行之后数组的边界 1.)我需要你的帮助来修复代码 2.)我的File1Conn是平面文件连接,而我想直接从foreach循环不断更新的变量User::FileName读取它。请帮助修改下面的代码 提前感谢。 这是我的平面文件:C# 导入具有动态列的文件,c#,sql-server,ssis,etl,flat-file,C#,Sql Server,Ssis,Etl,Flat File,我是SSIS和C#的新手。在SQL Server 2008中,我从.csv文件导入数据。现在我有了动态列。它们可以是大约22列(有时多多少少)。我创建了一个包含25列的临时表,并将数据导入其中。实际上,我导入的每个平面文件都有不同的列数。它们的格式都是正确的。我的任务是从.csv平面文件导入所有行,包括标题。我想把它放到一个作业中,这样我就可以每天将多个文件导入到表中 所以在for-each循环中,我有一个数据流任务,其中有一个脚本组件。我(在线研究)提出了下面的C代码,但我得到了错误: 索引超
正如您提到的,该文件具有动态的列数,在脚本组件中,您需要按分隔符计算列数,然后重定向到不同的输出 对于第二个问题,可以将变量指定给平面文件连接管理器连接字符串属性。然后可以直接读取脚本中的变量值
除了脚本组件之外,您可以使用虚拟分隔符创建“一列”平面文件源,然后在数据流任务中,您可以将列的数量读入变量,有条件地分割数据流,将输出重定向到不同的目标。可以在中找到一个示例,正如您提到的,该文件具有动态列数,在脚本组件中,您需要按分隔符计算列数,然后重定向到不同的输出 对于第二个问题,可以将变量指定给平面文件连接管理器连接字符串属性。然后可以直接读取脚本中的变量值
除了脚本组件之外,您可以使用虚拟分隔符创建“一列”平面文件源,然后在数据流任务中,您可以将列的数量读入变量,有条件地分割数据流,将输出重定向到不同的目标。在中可以找到一个示例,您的两个解决方案都已在代码中实现。My有多个列数不同的平面文件。在您的示例中,平面文件有3列,这是固定的。每个平面文件有不同的列数。列数据我所知,在脚本组件中,在运行时无法更改输出列的数量。因此,在您的案例中,您可以考虑:(a)第三方组件,或编写自定义数据流组件(b)在脚本组件读取文件并写入目标中的每个循环和控制流级别的脚本组件使用a)以及(c)如我建议的,将变量列文件视为“一列”文件,然后使用派生列(计算实际列)和条件拆分组件,您可以将输出导航到多个目标。您的两个解决方案都已在代码中实现。My有多个具有不同列数的平面文件。在您的示例中,平面文件有3列,这是固定的。每个平面文件具有不同的列数。据我所知,列数以s表示脚本组件输出列的数量在运行时无法更改。因此,在您的情况下,您可以考虑:(a)第三方组件,或编写自定义数据流组件(b)在脚本组件读取文件中为每个循环使用一个脚本组件,并在控制流级别将脚本组件写入目标和(c)就像我建议的那样,将变量列文件视为“一列”文件,然后使用派生列(计算实际列)和条件拆分组件,您可以将输出导航到多个目的地,而不是尝试将行发送到输出缓冲区,为什么不将它们发送到脚本中的最终目的地?另一个选项是BiML。与其尝试将行发送到输出缓冲区,为什么不将它们发送到最终目的地脚本中的所有选项?另一个选项是BiML。
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Windows.Forms;
using System.IO;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
private StreamReader SR;
private string File1;
public override void AcquireConnections(object Transaction)
{
// Get the connection for File1
IDTSConnectionManager100 CM = this.Connections.File1Conn;
File1 = (string)CM.AcquireConnection(null);
}
public override void PreExecute()
{
base.PreExecute();
SR = new StreamReader(File1);
}
public override void PostExecute()
{
base.PostExecute();
SR.Close();
}
public override void CreateNewOutputRows()
{
// Declare variables
string nextLine;
string[] columns;
char[] delimiters;
int Col4Count;
String[] Col4Value = new string[50];
// Set the delimiter
delimiters = ";".ToCharArray();
// Read the first line (header)
nextLine = SR.ReadLine();
// Split the line into columns
columns = nextLine.Split(delimiters);
// Find out how many Col3 there are in the file
Col4Count = columns.Length - 3;
//MessageBox.Show(Col4Count.ToString());
// Read the second line and loop until the end of the file
nextLine = SR.ReadLine();
while (nextLine != null)
{
// Split the line into columns
columns = nextLine.Split(delimiters);
{
// Add a row
File1OutputBuffer.AddRow();
// Set the values of the Script Component output according to the file content
File1OutputBuffer.SampleID = columns[0];
File1OutputBuffer.RepNumber = columns[1];
File1OutputBuffer.Product = columns[2];
File1OutputBuffer.Col1 = columns[3];
File1OutputBuffer.Col2 = columns[4];
File1OutputBuffer.Col3 = columns[5];
File1OutputBuffer.Col4 = columns[6];
File1OutputBuffer.Col5 = columns[7];
File1OutputBuffer.Col6 = columns[8];
File1OutputBuffer.Col7 = columns[9];
File1OutputBuffer.Col8 = columns[10];
File1OutputBuffer.Col9 = columns[11];
File1OutputBuffer.Col10 = columns[12];
File1OutputBuffer.Col11 = columns[13];
File1OutputBuffer.Col12 = columns[14];
File1OutputBuffer.Col13 = columns[15];
File1OutputBuffer.Col14 = columns[16];
File1OutputBuffer.Col15 = columns[17];
File1OutputBuffer.Col16 = columns[18];
}
// Read the next line
nextLine = SR.ReadLine();
}
}
}