其實這個問題好多年以前研究過:
https://blog.csdn.net/xpnew/article/details/6909902
最近因為需要統計日結月結,給同事寫了一套調用存儲過程的代碼。同時因為項目ORM層是通過SqlSugar實現的,就又研究了一下SqlSugar調用存儲過程的內容。
折騰了一番之后,對於【c#獲取存儲過程返回值】這個技術點,又有了新一層認識。下面寫一下要點總結:
一、核心內容是指定Command參數的Direction
MyCommand.Parameters["@return"].Direction = ParameterDirection.ReturnValue;
這個和以前的的看法是一樣的。只是這次經歷的研究,發現有很多細節在里面,在后面逐一列出
二、調用存儲過程的方法:GetScalar和ExecuteCommand
在SqlSugar當中,使用Direction 的辦法,這兩種調用方法都能正確地返回值。
但是這兩個方法,實際上是不一樣的:
GetScalar返回的是結果集(表格)的第一行、第一列。
ExecuteCommand是執行了存儲過程,成功更新/添加多少條。
具體來說:
■完全沒有執行任何更新、插入,返回-1
■只有UPDATE DELET INSERT 執行的結果會算在內,上圖的2/3/3分別是隨便添加了一個update更新了2行,刪除了原來的統計結果3條,重新計算了統計結果再插入也是3條。
■包含多個UPDATE DELET INSERT操作的時候,返回的結果是全部操作行數之和。
三、存儲過程里面的Select/Update和Return
在不太嚴謹的使用當中,可以用Select代替Return Value(前提是通過GetScalar 調用 )
存儲過程當中 這樣寫:
執行結果:
c#代碼調試:
不過當我做了一個簡單的干擾就不行了。
比如說我在最終返回之前添加了一個select
在SQL Server管理器里面:
C#代碼調試:
也就是說,使用Select返回結果是有局限的,不能在最終返回之前有任何其它的SELECT.
當然,UPDATE就更不行了。參見上一節。
總之,假如想把存儲過程當作一個有返回代碼的“函數”、“方法”看待的話,還是要用 OUTPUT或者ReturnValue
四、ReturnValue的其它細節
1、需要在執行之前添加到Command參數里。
以前在c#通過 ADO.net連接數據庫的時候,我好像驗證過,執行之前指定了返回參數才有這個處理,ADO.net不會自動處理。
SqlSugar里面這次驗證過了,不添加是不會自動生成這個參數的,看了源代碼也是這樣。
2、ReturnValue是“額外的”參數數量,如果出現了“使用了過多的參數數量”一類的異常,請檢查其它參數,從其它的參數上尋找問題。
3、參數的名稱無關緊要,只要不會干擾到其它傳入、傳出參數就行。