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

发布于 2024-09-11 10:32:51 字数 2014 浏览 5 评论 0原文

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

在我的代码中,我添加了一个名为 @RETURN_VALUE 的参数,其中 ReturnValue 方向优先于任何其他参数,但是当我使用 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

C# 代码

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;

I have a stored procedure, which returns the unique identifier after insertion @@identity. I tried it in the server explorer and it works as expected @RETURN_VALUE = [identifier].

In my code I added a parameter called @RETURN_VALUE, with ReturnValue direction first, than any other parameters, but when I run my query with ExecuteNonQuery() that parameter remains empty. I don't know what I've done wrong.

Stored Procedure

 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

C# Code

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

长亭外,古道边 2024-09-18 10:32:51

刚刚在我的盒子上尝试过,这对我有用:

在 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);
    }
}

Just tried on my box and this works for me:

In SQL Server:

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

In 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);
    }
}
ゞ花落谁相伴 2024-09-18 10:32:51

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

I solved the problem:
you have to set SqlCommand.CommandType to CommandType.StoredProcedure in order to get return values and/or output parameters. I haven't found any documentation about that, but now everything works.

左岸枫 2024-09-18 10:32:51

你在 TSQL 中得到了 EXEC 的值吗?我想知道重构 TSQL 是否会有帮助(并使用 SCOPE_IDENTITY() :

因此将:更改

COMMIT TRAN T1
RETURN @@IDENTITY

为:(

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

我还将其他 @@IDENTITY 更改为 SCOPE_IDENTITY( )


作为一个小的优化,您还可以使用:

return (int)retval.Value;

但是从我所看到的来看,这方面的事情应该“按原样”工作(因此为什么我专注于 TSQL )。

Do you get the value of you EXEC in TSQL? I wonder if refactoring the TSQL would help (and using SCOPE_IDENTITY():

so change:

COMMIT TRAN T1
RETURN @@IDENTITY

to:

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

(I would also change the other @@IDENTITY to SCOPE_IDENTITY())


As a minor optimisation, you could also use:

return (int)retval.Value;

but this side of things should have worked "as is" from what I can see (hence why I'm focusing on the TSQL).

乞讨 2024-09-18 10:32:51

有些人还可以使用这种简单而简短的方法来计算 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

Some one can also use this simple and short method to calculate return value from SP

In 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 always returns Int type value only.

and in 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;
}

You can also check your return value in SQL by using this command:

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
吃→可爱长大的 2024-09-18 10:32:51

您可以使用之前在普通查询中使用的标准方法,但在 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();

you can use standart ways that you use before in normal queries but in Sql command you must write EXEC before your store procedure name and dont use commandtype like this :

 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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文