ssis-将具有不同结构的多个csv加载到sql server

时间:2019-01-16 07:38:23

标签: sql-server ssis ssis-2012 ssis-2008

我有多个结构不同(列数不同,列名不同)的CSV文件(超过60个),我想将它们加载到SQL Server表中。

  • 每个CSV文件将被加载到不同的表中。
  • SSIS流程需要使用CSV结构自动创建表,并将CSV数据加载到表中。

我该怎么做?

2 个答案:

答案 0 :(得分:0)

您“可以”尝试以下方法。

创建带有1列的临时表以存储数据。 VARCHAR(MAX)+1个col来存储文件名

然后设置您的SSIS以将每一行加载到该列中(无列定界符) 您可能还需要将Header加载为数据行以获取列名。

然后您可以将ForEach循环到该表中

最后,您将编写一个存储过程来解析逗号分隔的列名,并动态创建目标表,并解析值并加载它们。

不是最有效的数据加载方式,但是如果文件很小,那么应该没问题...

答案 1 :(得分:0)

您可以在文件枚举器类型的Foreach循环中使用脚本任务来执行此操作。请注意,此示例旨在将数据发送到登台表,因为每个列都定义为VARCHAR(250)。您可能需要调整长度,其中250只是用于测试目的。创建的表以数据来自的文件命名,您将要确保不存在具有这些名称的表,否则将其删除。如果您希望此操作在已经存在相同名称的表时失败,则删除第一个SqlCommand.ExecuteNonQuery()调用,这是执行此步骤的步骤。在Foreach循环中,在索引0处添加一个变量以保存文件名,然后在脚本任务的ReadOnlyVariables字段中添加此变量。在下面的示例中,此变量为VariableWithFilePath

using System.Data.SqlClient;
using System.IO;
using System.Collections.Generic;
using System.Linq;


string connstr = @"Data Source=YourServer;Initial Catalog=YourDatabase;Integrated Security=SSPI;";

//get file path
string fullFileName = Dts.Variables["User::VariableWithFilePath"].Value.ToString();

//get only file name to be used when creating table
string fileName = Path.GetFileNameWithoutExtension(fullFileName);

DataTable dt = new DataTable();
using (StreamReader sr = new StreamReader(fullFileName))
{
    List<string> colNames = new List<string>();

    string firstLine = sr.ReadLine();
    string[] headers = firstLine.Split(',');

    foreach (string h in headers)
    {
        dt.Columns.Add(h);
        colNames.Add(h);
    }

    int columnCount = headers.Count();
    string line = sr.ReadLine();

    while (line != null)
    {
        string[] fields = line.Split(',');

        int currentLength = fields.Count();
        if (currentLength < columnCount)
        {
            //make sure fields from each row are kept together 
            while (currentLength < columnCount)
            {
                line += sr.ReadLine();
                currentLength = line.Split(',').Count();
            }
            fields = line.Split(',');
        }

        //load data table
        dt.Rows.Add(fields);
        line = sr.ReadLine();
    }
    string columns = string.Join(" VARCHAR(250), ", colNames);

    //command to drop table if it already exist
    string dropDDL = "IF (OBJECT_ID(N'DBO." + fileName + "') IS NOT NULL) DROP TABLE DBO." + fileName;

    //command to create new with same name as file
    string createDDL = "CREATE TABLE DBO." + fileName + " ( " + columns + " VARCHAR(250) )";

    using (SqlConnection conn = new SqlConnection(connstr))
    {
        SqlCommand sql = new SqlCommand();
        sql.Connection = conn;
        sql.CommandText = dropDDL;

        //drop table if exists
        conn.Open();
        sql.ExecuteNonQuery();

        //create table
        sql.CommandText = createDDL;
        sql.ExecuteNonQuery();

        //load SQL Server table from data table
        using (SqlBulkCopy blkCpy = new SqlBulkCopy(conn))
        {
            blkCpy.DestinationTableName = fileName;
            blkCpy.WriteToServer(dt);
        }
    }

}