2010-07-22 103 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();