繁体   English   中英

将缺少列的 CSV 导入 MS SQL 服务器表

[英]Import CSV with missing columns into MS SQL Server table

假设我有一个像这样的 csv 文件:

field1 field3
0      1
1      2

对应的表格如下所示:

field1 field2 field3
null   null   null
...    ...    ...

假设所有字段都可以为空,我如何将 csv 文件导入表中? 我知道我可以使用格式化程序批量BULK INSERT ,但我无法通过bcp生成格式化程序,因为与本地 SQL 服务器的连接失败(奇怪?)有没有更好的方法来解决这个问题?

您可以创建一个仅包含数据 csv 文件中的列的临时表,然后使用 BCP 将数据加载到其中。 之后使用INSERT INTO...SELECT..FROM将数据加载到目标表。 有关更多详细信息,请参阅此答案

将 csv/txt 分隔文件移动到 SQL 服务器表中时,使用它们可能会很棘手。 我让用户弄乱了列或列太多等。我的解决方案是首先使用 stream 读取器读取文件,然后将 header 行添加到数组中,将数据本身放入自己的数组中。 然后我循环遍历 header 数组并将每个值添加到空 DataTable 的列中。 所以现在我有一个包含 header 名称(代表 SQL 服务器中的列名)的数据表和另一个包含实际数据的数据表。 然后查询SQL服务器表,得到一个列名的字典列表:

        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 值匹配,如果我有匹配项,请使用批量复制到 map 列。

             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 表匹配的有效列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM