将 csv/txt 分隔的文件移动到 SQL Server 表中时可能会很棘手。我让用户弄乱了列或列太多等。我的解决方案是首先使用流阅读器读取文件,然后将标题行添加到数组中,将数据本身放入自己的数组中。然后我循环遍历标题数组并将每个值添加到空 DataTable 中的列中。
所以现在我有一个包含标题名称(代表 SQL Server 中的列名)的数据表和另一个包含实际数据的数据表。
然后查询 SQL server Table 以获取 Column 名称的字典列表:
Dictionary<int, string> SQLTableColNamesDict = new Dictionary<int, string>();
string Command = " SELECT COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'table name' ";
using (SqlConnection Connection = new SqlConnection(sqlconnectionstring))
{
Connection.Open();
using (SqlCommand cmd = new SqlCommand(Command, Connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
SQLTableColNamesDict.Add((int)reader[1], (string)reader[0].ToString().ToUpper());
}
}
}
}
然后循环遍历 header 数组,看看字典列表是否匹配 header 值,如果有匹配则使用 Bulk Copy 映射列。
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlconnectionstring))
{
bulkCopy.DestinationTableName = SQLdestinationTable;
bulkCopy.BatchSize = dtWithColNames.Rows.Count;
foreach (string columnFromFile in firstRowHeaderFromFileArray)
{
string DesintationOrdinalPostion = "";
string DesintationColName = "";
if (SQLTableColNamesDict.ContainsValue(columnFromFile.ToUpper()))
{
DesintationOrdinalPostion = SQLTableColNamesDict.First(item => item.Value == columnFromFile.ToUpper()).Key.ToString();
DesintationColName = SQLTableColNamesDict.First(item => item.Value == columnFromFile.ToUpper()).Value.ToString();
}
if (DesintationOrdinalPostion != "")
// if (colFound != null)
{
SqlBulkCopyColumnMapping col = new SqlBulkCopyColumnMapping();
// col.SourceColumn = columnFromFile;
col.SourceColumn = DesintationColName;
col.DestinationOrdinal = Convert.ToInt32(DesintationOrdinalPostion);
col.DestinationColumn = columnFromFile.ToUpper();
bulkCopy.ColumnMappings.Add(col);
}
}
然后最后进行批量复制
int recordCount = 0;
recordCount = dtWithColNames.Rows.Count;
// Write from the source to the destination.
try
{
bulkCopy.WriteToServer(dtWithColNames);
}
catch (Exception error)
{
}
finally
{
bulkCopy.Close();
}
这应该允许传输工作,即使 csv 文件可能带有额外的列格式错误并且只接受与您的 SQL 表匹配的有效列。