2011-11-23 76 views
1

我目前有一個使用C#編寫的WinForms應用程序。C# - 批處理執行存儲過程

我們所有的更新都是通過執行存儲過程完成的。我們在一個屏幕上有一個情況,在該屏幕上有多達60個更新。目前,每次更新呼叫都會逐一處理,而且客戶端和服務器之間連接速度較慢的某些客戶端遇到速度問題。我非常確定,如果我可以一次將所有這些調用發送到數據庫,那麼它會節省很多客戶端的等待時間(目前對於這60個調用中的每一個來說,ExecuteNonQuery被調用並且客戶機等待在繼續之前爲true/false結果,這導致延遲)。

將所有這些調用捆綁到一個SQL調用中的最佳方式是什麼?正在考慮將所有代碼放入事務中,但需要儘可能避免鎖定,因爲在任何給定點上都有許多併發用戶使用系統。

編輯:存儲特效的目的是從字面上更新服務器上的記錄。我們甚至不需要正在執行的存儲過程的任何響應。從本質上講,我希望捆綁一堆調用的代碼的下方進一個電話,想知道這樣做的最好辦法是

 public virtual bool Update(DataRow dataRow, Guid userId) 
    { 
     SqlCommand cm = null; 
     bool ret = true; 
     try 
     { 
      cm = Utilities.GetSqlUpdateCommand(dataRow, userId); 
      ExecuteNonQuery(cm);    
     } 
     catch (SqlException ex) 
     { 
      LogDataAccessBaseError(ex); 
      ret = false; 
      throw; 
     } 
     finally 
     { 
      if (cm != null) 
      { 
       cm.Dispose(); 
      } 
     } 

     return ret; 
    } 

回答

0

一個簡單的解決辦法是實現一個新的存儲過程,採取必要的參數和在服務器上執行所有必要的存儲過程。

另一種完全在客戶端完全實現的方式是,正如您自己指出的那樣,使用事務。由於我對你的存儲過程應該做什麼一無所知,所以我不能說在這裏如何避免鎖定。

0

是否需要按特定順序進行呼叫?如果不是,多線程可能會有所幫助。

您的問題的最佳答案取決於您對過程的每一端有多少控制權。理想情況下,您只需進行一次調用即可返回一大塊包含您需要的數據的數據。請記住,從存儲過程返回數據時,存儲過程可以返回多個select語句,並且可以遍歷返回的記錄集。所以一個存儲過程可能會返回你需要的一切。也許根據查詢需要什麼參數將所有內容封裝在一個存儲過程中是沒有意義的,但是至少可以將它包含到少數幾個調用中。

+0

根據您需要什麼樣的準確性,NO LOCK查詢提示可以幫助您避免鎖定。如果你在處理金錢,那麼忘記我甚至說過。但是,如果您處理的是網頁在過去24小時內收到的點擊次數,並且您不在乎它是否已關閉2%,那麼它可能會有所幫助。 –

0

您使用的是SQL Server 2008或更高版本,並且所有存儲過程調用都是相同的(除個別參數外)?

如果是這樣,您可以考慮創建一個需要Table-Valued ParameterADO)的存儲過程的版本。這將允許您將所有行傳遞到SQL Server作爲單個表。


如果沒有,那麼我假定GetSqlUpdateCommand目前正在建造與所存儲的程序名稱的SqlCommand並添加適當的參數。一種不同的方法是:

更改GetSqlUpdateCommand,以便它可以接受現有的SqlCommand對象。然後它會追加一個exec StoredProcedure @Parm1,@Parm2,@Parm2的新呼叫,並添加這些參數。它需要確保它爲所添加的參數使用新名稱,以便它不會與其他exec調用發生衝突。您可能還需要調整此功能,以便它可以檢測您何時接近可傳遞參數數量的限制,此時應執行此命令,然後創建一個新命令。

E.g.它建立起來像一個文本命令:

exec MegaProcedure @Parm1,@Parm2,@Parm3 
exec MegaProcedure @Parm4,@Parm5,@Parm6 
exec MegaProcedure @Parm7,@Parm8,@Parm9 

最後,我想你不明白交易是/不 - 他們沒有神奇的多個調用捆綁在一起,使他們以更少的開銷/往返執行倍。它們純粹是一種簡單的工作可以回滾的機制,所以它們在這裏不起作用。

(而且,事實上,在SQL每條語句在事務內運行無論如何 - 它只是在默認情況下,該交易將自動一份聲明中啓動時打開,並在該語句成功完成承諾)