C# 从ADO.NET中的存储过程获取返回值

C# 从ADO.NET中的存储过程获取返回值,c#,ado.net,C#,Ado.net,我有一个存储过程,它在插入后返回唯一标识符@@identity。我在服务器资源管理器中尝试了它,它按预期工作@RETURN\u VALUE=[identifier] 在我的代码中,我添加了一个名为@RETURN\u VALUE的参数,该参数的返回值方向优先于任何其他参数,但当我使用ExecuteNonQuery()运行查询时,该参数仍然为空。我不知道我做错了什么 存储过程 ALTER PROCEDURE dbo.SetAuction ( @auctionID int, @itemID

我有一个存储过程,它在插入后返回唯一标识符
@@identity
。我在服务器资源管理器中尝试了它,它按预期工作
@RETURN\u VALUE=[identifier]

在我的代码中,我添加了一个名为
@RETURN\u VALUE
的参数,该参数的返回值方向优先于任何其他参数,但当我使用
ExecuteNonQuery()
运行查询时,该参数仍然为空。我不知道我做错了什么

存储过程

 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;

您是否在TSQL中获得了you
EXEC
的值?我想知道重构TSQL是否有帮助(并使用
SCOPE\u IDENTITY()

因此,改变:

COMMIT TRAN T1
RETURN @@IDENTITY
致:

(我还要将另一个
@@IDENTITY
更改为
SCOPE\u IDENTITY()


作为次要优化,您还可以使用:

return (int)retval.Value;

但从我所看到的情况来看,事情的这一面应该“按原样”运作(因此我将重点放在TSQL上)。

刚刚在我的盒子上试用过,这对我来说很有用:

在SQL Server中:

DROP PROCEDURE TestProc;
GO
CREATE PROCEDURE TestProc
AS
   RETURN 123;
GO
在C中#

我解决了这个问题:
您必须将
SqlCommand.CommandType
设置为
CommandType.StoredProcedure
,才能获取返回值和/或输出参数。我还没有找到任何关于这方面的文档,但现在一切都正常了。

有些人还可以使用此简单而简短的方法从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#

还可以使用以下命令检查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

您可以使用以前在正常查询中使用的标准方式,但在Sql命令中,您必须在存储过程名称之前写入EXEC,并且不要像这样使用commandtype:

 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();

当您说“empty”时,您会收到一个异常,表示
为null?(如果为null,则强制转换将失败)。或者它是0?顺便说一句,
@@IDENTITY
是危险的;您应该改为使用
SCOPE\u IDENTITY()
。在这种情况下,将返回值0:请尝试SCOPE\u IDENTITY(),或者至少一个测试值更改了您的建议,但没有效果。我使用“EXEC SetAuction@auctionID,…”作为CommandText。如果从服务器资源管理器(Visual Studio)运行它,我会得到返回值。我扩展了示例。也许您可以尝试此操作。
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;
}
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
 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();