2011-08-23 20 views
14

我正在將一些基於存儲過程的報告例程轉換爲在C#中運行。總的想法是使用C#/ .NET Framework的所有奇蹟,然後將結果反饋回數據庫。除了昨天遇到的一個問題,今天解決之外,所有事情都一直在順風順水。獲取SqlBulkCopy以兌現列名

要進行導入,我以編程方式創建DataTable並使用SqlBulkCopy將結果移動到服務器。

例如

DataTable detail = new DataTable(); 
detail.Columns.Add(new DataColumn("Stock", Type.GetType("System.Decimal"))); 
detail.Columns.Add(new DataColumn("Receipts", Type.GetType("System.Decimal"))); 
detail.Columns.Add(new DataColumn("Orders", Type.GetType("System.Decimal"))); 

導入表的字段按以下順序排列。

... 
Stock decimal(18,4), 
Orders decimal(18,4), 
Receipts decimal(18,4) 
... 

實質上,收據值進入訂單,反之亦然。

很明顯,這是因爲SqlBulkCopy似乎不遵守我告訴它填充的列名 - 它只是順序排列。

這對我來說是一個問題,因爲我們使用Redgate的SQL Compare。將數據庫中的更改推送到另一個數據庫時,不一定保留列的序號位置。 (例如,如果插入新列作爲第三個序號字段,則SQL比較將只將其附加到同步表上,使其成爲最後一列)。

這嚴重影響了我的解決方案。現在,這些只是'導入'表,所以如果需要的話,我可以刪除並重新創建它們,作爲序號完整的任何遷移腳本的一部分。我寧願不這樣做。

有沒有辦法強制SqlBulkCopy尊重你告訴它填充的列名稱?

+0

P.S.,在Red Gate SQL Compare中有一個名爲「強制列順序」的項目選項,可在新列同步期間保持列的順序相同。 (請注意,這需要對錶格進行刪除和重新構建,但在過去絕對需要時對我很有幫助。) – Funka

回答

14

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.columnmappings.aspx

但是,如果列數不同,或序號位置不 一致,則必須使用ColumnMappings以確保數據 複製到正確的列。

對於示例代碼參見「映射列」在http://www.sqlteam.com/article/use-sqlbulkcopy-to-quickly-load-data-from-your-client-to-sql-server

+0

正是我需要的。謝謝。 –

+0

我的回答下面解決了訂單問題.. :) – ttomsen

+0

例外,我想要(列數差異) –

0

我可能失去了一些東西,但爲什麼不能你改變列的順序?我通常不會親手製作我的DataTable。我使用方法SqlDataAdapter,使用"select * from targetTable"查詢。所以我總是確定我的DataTable適合目標表。

1

在項目選項中,SQL對比強制列順序中有一個選項。這將生成一個腳本來重新排列列。我可能是錯的,但我認爲這個操作可能需要重建表,所以請謹慎使用,因爲這可能會影響性能。但是,該腳本將保留表格數據。

9

下面是解決這個'錯誤'的解決方案。

默認值是按序號/位置映射。

在我的情況下,我是從一個隨機順序的電子表格加載。這裏有一個快速解決方案(表是我的DataTable是「出來序秩序」,並bulkCopy是SqlBulkCopy的對象)

foreach (DataColumn col in table.Columns) 
{ 
    bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName); 
} 

正如你所看到的,我只是迫使它的名字重新整理,即使名稱是相同的。

+0

這節省了我幾個小時!非常感謝... –