2010-07-22 55 views
16

我知道有幾乎相同的標題有另一個問題,但它不回答我的問題。 我有一個存儲過程,它在插入後返回唯一標識符(@@ identity)。我在服務器資源管理器中試過,它按預期工作(@RETURN_VALUE = [identifier])。 在我的代碼中,我添加了一個名爲「@RETURN_VALUE」的參數,其返回值的方向優先於任何其他參數,但是當我使用ExecuteNonQuery()運行查詢時,該參數仍爲空。我不知道我做錯了什麼。 我的存儲過程:在ADO.NET中獲取存儲過程的返回值

ALTER PROCEDURE dbo.SetAuction 
(
    @auctionID int, 
    @itemID int, 
    @auctionType tinyint, 
    @reservationPrice int, 
    @maxPrice int, 
    @auctionEnd datetime, 
    @auctionStart datetime, 
    @auctionTTL tinyint, 
    @itemName nchar(50), 
    @itemDescription nvarchar(MAX), 
    @categoryID tinyint, 
    @categoryName nchar(50) 
) AS 
IF @auctionID <> 0 
    BEGIN 
    BEGIN TRAN T1 

    UPDATE Auction 
    SET AuctionType = @auctionType, 
    ReservationPrice = @reservationPrice, 
    MaxPrice = @maxPrice, 
    AuctionEnd = @auctionEnd, 
    AuctionStart = @auctionStart, 
    AuctionTTL = @auctionTTL 
    WHERE AuctionID = @auctionID; 

    UPDATE Item 
    SET 
    ItemName = @itemName, 
    ItemDescription = @itemDescription 
    WHERE 
    ItemID = (SELECT ItemID FROM Auction WHERE AuctionID = @auctionID); 

    COMMIT TRAN T1 

    RETURN @auctionID 
    END 
ELSE 
    BEGIN 
    BEGIN TRAN T1 
    INSERT INTO Item(ItemName, ItemDescription, CategoryID) 
    VALUES(@itemName, @itemDescription, @categoryID); 

    INSERT INTO Auction(ItemID, AuctionType, ReservationPrice, MaxPrice, AuctionEnd, AuctionStart, AuctionTTL) 
    VALUES(@@IDENTITY,@auctionType,@reservationPrice,@maxPrice,@auctionEnd,@auctionStart,@auctionTTL); 
    COMMIT TRAN T1 
    RETURN @@IDENTITY 
    END 

而且我的代碼是:

   cmd.CommandText = cmdText; 
       SqlParameter retval = new SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Int); 
       retval.Direction = System.Data.ParameterDirection.ReturnValue; 
       cmd.Parameters.Add(retval); 
       cmd.Parameters.AddRange(parameters); 
       cmd.Connection = connection; 

       connection.Open(); 
       cmd.ExecuteNonQuery(); 

       return (int)cmd.Parameters["@RETURN_VALUE"].Value; 
+0

當你說'空' - 你會得到一個異常說'價值'爲空? (如果它爲空,則投射失敗)。還是0? – 2010-07-22 13:17:44

+0

它的值爲0. – WebMonster 2010-07-22 13:20:47

+4

順便說一句,'@@ IDENTITY'是危險的;你應該使用'SCOPE_IDENTITY()'來代替。 – 2010-07-22 13:21:07

回答

22

剛試過在我的盒子,這對我的作品:

在SQL Server:

DROP PROCEDURE TestProc; 
GO 
CREATE PROCEDURE TestProc 
AS 
    RETURN 123; 
GO 

在C#

 string cnStr = "Server=.;Database=Sandbox;Integrated Security=sspi;"; 
     using (SqlConnection cn = new SqlConnection(cnStr)) { 
      cn.Open(); 
      using (SqlCommand cmd = new SqlCommand("TestProc", cn)) { 
       cmd.CommandType = CommandType.StoredProcedure; 
       SqlParameter returnValue = new SqlParameter(); 
       returnValue.Direction = ParameterDirection.ReturnValue; 
       cmd.Parameters.Add(returnValue); 

       cmd.ExecuteNonQuery(); 
       Assert.AreEqual(123, (int)returnValue.Value); 
      } 
     } 
+0

id get的值爲0. – WebMonster 2010-07-22 13:31:56

+0

我擴展了這個例子。也許你會試試這個。 – 2010-07-22 14:00:37

3

你得到你EXEC在TSQL的價值?我不知道重構的TSQL將有助於(使用SCOPE_IDENTITY()

所以更改:

COMMIT TRAN T1 
RETURN @@IDENTITY 

到:

SET @auctionID = SCOPE_IDENTITY() 
COMMIT TRAN T1 
RETURN @auctionID 

(我也想改變對方@@IDENTITYSCOPE_IDENTITY()


作爲次要優化,您還可以使用:

return (int)retval.Value; 

而是事物本方應該工作過「原樣」從我所看到的(所以爲什麼我專注於TSQL)。

+0

已更改您的建議,但無效。 我使用「EXEC SetAuction @auctionID,...」作爲CommandText。如果我從服務器資源管理器(Visual Studio)運行它,我會得到返回值。 – WebMonster 2010-07-22 13:28:30

4

我解決了這個問題: 你必須設置SqlCommand.CommandTypeCommandType.StoredProcedure爲了得到返回值和/或輸出參數。我還沒有找到任何有關這方面的文件,但現在一切正常。

1

一些人們也可以使用這個簡單的和短期的方法來從SP

計算返回值在SQL:

Create Table TestTable 
(
Int Id 
) 

CREATE PROCEDURE Proc_TestProc 
@Id 
AS 
    Begin 
    Set NOCOUNT ON //Use this line if you don't want to return any message from SQL 

    Delete from TestTable where Id = @Id 
    return 1 

    Set NOCOUNT OFF //NOCOUNT OFF is Optional for NOCOUNT ON property 
    End 

Sql Server中始終只返回int類型的值。

和C#

using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ToString())) 
using (SqlCommand cmd = new SqlCommand("Proc_TestProc", conn)) 
{ 
cmd.CommandType = CommandType.StoredProcedure; 

cmd.Parameters.AddWithValue("@Id", 1); 
var returnParameter = cmd.Parameters.Add("@ReturnVal", SqlDbType.Int); 
returnParameter.Direction = ParameterDirection.ReturnValue; 

conn.Open(); 
cmd.ExecuteNonQuery(); 
var result = returnParameter.Value; 
} 

您也可以使用此命令檢查SQL的返回值:

DECLARE @return_status int; 
EXEC @return_status = dbo.[Proc_TestProc] 1; 
SELECT 'Return Status' = @return_status; 
print 'Returned value from Procedure: ' + Convert(varchar, @return_status); // Either previous or this line both will show you the value of returned value 
0

您可以使用您的正常查詢之前使用非標準的方式,但在Sql命令中,您必須在存儲過程名稱之前編寫EXEC,並且不要使用如下所示的命令類型:

SqlConnection con = new SqlConnection(["ConnectionString"]) 
    SqlCommand com = new SqlCommand("EXEC _Proc @id",con); 
    com.Parameters.AddWithValue("@id",["IDVALUE"]); 
    con.Open(); 
    SqlDataReader rdr = com.ExecuteReader(); 
    ArrayList liste = new ArrayList(); 
    While(rdr.Read()) 
    { 
    liste.Add(rdr[0]); //if it returns multiple you can add them another arrays=> liste1.Add(rdr[1]) .. 
    } 
    con.Close();