我有多个结构不同(列数不同,列名不同)的CSV文件(超过60个),我想将它们加载到SQL Server表中。
我该怎么做?
答案 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);
}
}
}