2011-12-23 48 views
3

相對簡單的問題。
Table AID int PK,獨特的Name varchar(500)cola, colb
Table B有一個外鍵Table ATSQL大量插入關係數據,W /外鍵Upsert

因此,在應用程序中,我們將表A和表B的記錄生成到內存中的DataTable中。

我們將在大量「客戶」上生成數千個這樣的記錄。

最後我們打電話來存儲這些記錄。但是,表A中的記錄可能已經存在於數據庫中,因此我們需要獲取已存在記錄的主鍵,並插入缺少的記錄。然後用正確的外鍵插入表B的所有記錄。

建議解決辦法:

我正在考慮派遣一個XML文檔到SQL Server作爲一個行集開到TableVarA,更新TableVarA與已存在的記錄的主鍵,然後插入缺失的記錄,輸出到TableVarNew,然後我選Name和主鍵TableVarA工會全部TableVarNew

然後在代碼中將正確的FK填充到內存中的TableB中,並使用SqlBulkCopy插入所有這些記錄。

這聽起來像是一個很好的解決方案嗎?如果是這樣,在內存中填充FK的最佳方法是TableB與返回的DataSet中的主鍵匹配。

回答

2

聽起來像一個計劃 - 但我認爲Table A處理可以更簡單(單在內存中的表/表變量應該是足夠了):

  • 有一個TableVarA,其中包含Table A
  • 所有行
  • 更新ID與他們的ID的所有現有行(應該是在一個SQL語句是可行的)
  • 插入所有非現有行(即仍然有一個空的ID)到Table A並記錄他們的ID

這可能一切發生在一個單一的表變量 - 我不明白爲什麼你需要複製周圍的東西....

一旦你處理你的Table A,就像你說的,更新Table B的外鍵並一次性批量插入這些行。

什麼我不是很清楚是怎麼Table B引用Table A - 你剛纔說的它有一個FK,但你沒有指定它是在(假設ID)什麼樣的列。那麼Table B的行是如何針對新行的Table A引用的?尚未插入,因此Table A中沒有ID呢?

+0

這將在唯一的名稱上完成。 插入表A的哪個部分是你在談論改變?這不是從兩個表的變量中選擇一個聯合,而是使用TableVarNew的結果更新TableVarA並將其作爲DataSet返回? – TrevDev 2011-12-23 22:37:37

+0

此外,我看到你的答案:http://stackoverflow.com/questions/3006472/fast-insert-relationalnormalized-data-tables-into-sql-server-2008-database 而這聽起來很聰明,但似乎更多地涉及數據導入,而不是優化將會發生的事情。 IE:許多客戶會很多時間發送很多記錄,所以試圖確保我們快速插入所有這些記錄非常重要。 – TrevDev 2011-12-23 22:42:08

+0

@Thx:我不喜歡你打算至少使用兩個(或三個)不同的「TableA」變量併合並的事實。我認爲你可以用一個TableA變量來完成所有必要的操作。另外:是的,也許是用SqlBulkCopy把所有東西都推送到服務器的想法,然後做所有的修復工作並不是什麼壞主意! – 2011-12-24 09:20:53

0

這是一個比完整答案更多的評論,但我已經沒有空間了,所以請不要因爲不滿足答案標準而將它投票。

我擔心的是,評估一組丟失的密鑰,然後大量插入,您會冒險將密鑰添加到其他位置。你說這可能來自大量的客戶,所以這將會發生。是的,你可以把它包裝在一個大的交易中,但大交易是生豬會鎖定其他客戶。

我的想法是處理那些有散裝鑰匙的人,假設沒有PK風險會被刪除。 TVP是有效的,但您需要明確知道處理過的內容。我認爲你需要首先在Name上搜索以獲得存在的PK列表,然後通過TVP處理該列表。

對於數據完整性,通過根據需要創建PK的存儲過程一次處理剩下的一個。

成千上萬的記錄並不可怕(數以百萬計)。大量的「客戶」是可怕的部分。