2011-01-28 113 views
3

我有一個包含10個屬性的客戶實體。C#/ SQL:在一個事務中執行多個插入/更新

  • 其中7個屬性保存在客戶表中。
  • 其中3個屬性保存在測試表中。

測試表中的3個屬性是CustomerId,Label,Text。

當我詢問這3個屬性,我得到3集是這樣的:

CustomerId | Label | Text 
1005  | blubb | What a day 
1006  | hello | Sun is shining 
0007  |  | 

當我救他們,我必須在測試表

打電話給我的存儲過程3次在我的SP我檢查其數據集與特定的customerId AND標籤已經存在 然後我做一個UPDATE或INSERT。

你將如何與所有CommandText,CommandType,ExecuteNonQuery等東西調用存儲過程3次?

+0

是有代表客戶的對象,還是要插入測試表的實體? – msarchet 2011-01-28 15:11:41

回答

8

最簡單的方法是:使用TransactionScope類。

簡而言之呼叫成塊,如:

using(TransactionScope ts = new TransactionScope()){ 

    using(SqlConnection conn = new SqlConnection(myconnstring) 
    { 
     conn.Open(); 
... do the call to sproc 

     ts.Complete(); 
     conn.Close(); 
    } 
} 

[編輯]我還添加了SqlConnection的,因爲我是這個模式非常有範。 using關鍵字確保連接關閉,如果發生錯誤,transcation回滾

1

好了,的SqlTransaction跨越了三個的ExecuteNonQuery是最簡單的,但一些備選方案:

  • 使用XML數據類型傳遞作爲XML所有三個;將sproc中的XML(SQL服務器具有此功能)解析爲3條記錄
  • 使用「表值參數」在單個調用中傳遞它們 - 注意,這需要在DB處額外定義以表示結構化數據
  • 如果數據量龐大(3000而不是3),使用SqlBulkCopy到一個臨時表中,然後運行一個存儲過程將數據移動到真實表中的一個基於集的操作

最後,提防「內部平臺效應」 - 聽起來有點像數據庫中的數據庫。

+0

你有我的一個小片段的跨越3 ExecuteNonQuery的sqltransaction,請嗎? – Elisabeth 2011-01-28 15:29:24

+0

@Lisa我相信MSDN有... http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.aspx – 2011-01-28 15:37:07

0

您應該將INSERT封裝到事務中。不好的方法是在ADO.NET中使用TransactionScope,好的方法是編寫一個存儲過程,並在您的proc中寫入BEGIN和COMMIT/ROLLBACK您的事務。您不希望在維護事務時來回切換客戶端到服務器,因爲您將損害concurreny和性能(在事務結束前插入的資源將被鎖定)。

BEGIN TRAN 開始嘗試這 INSERT INSERT COMMIT TRAN END TRY BEGIN CATCH PRINT ERROR_MESSAGE() - 你可以用扔在SQL Server 2012中,以retrhrow錯誤 ROLLBACK END CATCH

相關問題