簡體   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