导入具有动态列的文件

Posted

技术标签:

【中文标题】导入具有动态列的文件【英文标题】:Importing a File with Dynamic Columns 【发布时间】:2015-10-06 15:44:36 【问题描述】:

我是 SSIS 和 C# 的新手。在 SQL Server 2008 中,我从 .csv 文件导入数据。现在我有了动态的列。它们可以是大约 22 列(有时或多或少)。我创建了一个包含 25 列的临时表并将数据导入其中。本质上,我导入的每个平面文件都有不同数量的列。它们都是正确格式的。我的任务是从 .csv 平面文件中导入所有行,包括标题。我想把它放在一个工作中,这样我就可以每天将多个文件导入表中。

所以在 for each 循环中,我有一个数据流任务,其中有一个脚本组件。我想出了(在线研究)下面的 C# 代码,但出现错误:

索引超出了数组的范围。

我尝试使用 MessageBox 查找原因,发现它正在读取第一行,并且在第一行之后索引超出了数组的范围。

1.) 我需要您的帮助来修复代码

2.) 我的 File1Conn 是平面文件连接,而不是我想直接从我的 foreach 循环不断更新的变量 User::FileName 中读取它。请帮忙修改下面的代码。

提前致谢。

这是我的平面文件:

https://drive.google.com/file/d/0B418ObdiVnEIRnlsZFdwYTRfTFU/view?usp=sharing

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();

    



【问题讨论】:

与其尝试将行发送到输出缓冲区,不如直接在脚本中将它们发送到最终目的地?另一种选择是 BiML。 【参考方案1】:

正如您提到的文件具有动态数量的列,在您的脚本组件中,您需要通过分隔符计算列数,然后重定向到不同的输出。

对于第二个问题,您可以将变量分配给平面文件连接管理器连接字符串属性。然后就可以直接读取脚本中的变量值了。

除脚本组件外,您可以使用虚拟分隔符创建“一列”平面文件源,然后在数据流任务中,您可以将列数读入变量,有条件地拆分数据流,重定向输出到不同的目的地。可以在http://sqlcodespace.blogspot.com.au/2015/03/ssis-design-pattern-handling-flat-file.html找到一个示例

【讨论】:

您的两个解决方案都已在代码中实现。我有多个具有不同列数的平面文件。在您的示例中,您的平面文件有 3 列是固定的。每个平面文件都有不同的列数。列数 据我所知,在脚本组件中,输出列的数量在运行时无法更改。因此,在您的情况下,您可以考虑:(a)第三方组件,或编写自定义数据流组件(b)在控制流级别使用 for each 循环和脚本组件,在脚本组件中读取文件并写入目标(c) 就像我建议的将可变列文件视为“一列”文件,然后通过使用派生列(计算实际列)和条件拆分组件,您可以将输出导航到多个目的地

以上是关于导入具有动态列的文件的主要内容,如果未能解决你的问题,请参考以下文章

具有动态列的数据表

具有动态列的 MySQL 数据透视表查询

具有动态列的 MySQL 数据透视表查询

具有动态列的数据表

WPF DataGrid 将单元格绑定到具有动态列的数据模型

具有动态生成列、聚合函数和无聚合列的 SQL Pivot