在c#中检索SQL Server输出变量

本文关键字:Server 输出 变量 SQL 检索 | 更新日期: 2023-09-27 18:16:46

我有一个存储过程:

ALTER PROCEDURE [dbo].[pr_Tbl_Test_Insert]
    @guidid uniqueidentifier output,
    @sname nvarchar(50)
AS
-- INSERT a new row in the table.
INSERT [dbo].[Tbl_Test]
(
    [id],
    [name]
)
VALUES
(
    ISNULl(@guidid, (newid())),
    @sname
)

我需要id在c#中,把它放在output在c#中:

cmd.Parameters.AddWithValue("@guidid",_id);//_id is SqlGuid
cmd.Parameters.AddWithValue("@sname", "mehdi");
cmd.ExecuteNonQuery();
MessageBox.Show(_id.ToString());

但是消息框显示空值!!

如何返回id?

我把它改成:

ALTER PROCEDURE [dbo].[pr_Tbl_Test_Insert] 
  @guidid uniqueidentifier output, 
  @sname nvarchar(50) 
AS 
DECLARE @NewID UNIQUEIDENTIFIER 
SET @NewID = newid(); 
-- INSERT a new row in the table. 
INSERT [dbo].[Tbl_Test]([id], [name]) VALUES(@NewID, @sname); 
SET @guidid = @NewID 
c#

SqlParameter outparam = cmd.Parameters.Add("@guidid",SqlDbType.UniqueIdentifier);
outparam.Direction = ParameterDirection.Output;
cmd.Parameters.AddWithValue("@sname", "mehdi");
cmd.ExecuteNonQuery();
MessageBox.Show(_id.Value.ToString());

但是它没有返回任何东西

在c#中检索SQL Server输出变量

首先-如果它是一个OUTPUT参数,你不能在c#中使用.AddWithValue -你需要使用:

SqlParameter outParam = cmd.Parameters.Add("@guidid", SqlDbType.Uniqueidentifier);
outParam.Direction = ParameterDirection.Output;

,而且,在您的T-SQL代码中,您需要将新值分配给输出参数!

ALTER PROCEDURE [dbo].[pr_Tbl_Test_Insert]
  @guidid uniqueidentifier output,
  @sname nvarchar(50)
AS
DECLARE @NewID UNIQUEIDENTIFIER
SET @NewID = newid();
-- INSERT a new row in the table.
INSERT [dbo].[Tbl_Test]([id], [name]) VALUES(@NewID, @sname);
SET @guidid = @NewID

更新:如果你在你的SQL Server Mgmt Studio运行这个-它显示任何东西吗?

DECLARE @insertedID UNIQUEIDENTIFIER
EXEC dbo.pr_Tbl_Test_Insert @guidid = @insertedID OUTPUT,
                            @sname = N'TestUser' -- nvarchar(50)
SELECT @insertedID

和在你的c#中-你必须读取在调用ExecuteNonQuery之后的输出参数的值!

SqlParameter outparam = cmd.Parameters.Add("@guidid",SqlDbType.UniqueIdentifier);
outparam.Direction = ParameterDirection.Output;
cmd.Parameters.AddWithValue("@sname", "mehdi");
cmd.ExecuteNonQuery();
Guid newlyInsertedID = new Guid(cmd.Parameters["@guidid"].Value);
MessageBox.Show(newlyInsertedID.ToString());

在执行查询之前,需要指定参数的方向,在本例中为输出。例如:

cmd.Parameters.AddWithValue("@guidid",_id);//_id is SqlGuid
cmd.Parameters.AddWithValue("@sname", "mehdi");
cmd.Parameters["@guidid"].Direction = ParameterDirection.Output
cmd.ExecuteNonQuery();
MessageBox.Show(cmd.Parameters["@guidid"].Value.ToString());

您需要使用一个允许您指定ParameterDirection的构造函数来构造SqlParameter,例如这个。或者,构造你的参数,然后使用direction属性设置方向。

在MSDN上查看此链接以获取更多信息

为什么要将@guidid唯一标识符输出设置为输出参数?这意味着一旦执行存储过程,它将覆盖它。如果这是您的目的,那么您需要在insert语句之后添加一条语句,将输出参数设置为您想要的值。像这样:选择@guidid = @generatedID。是的,看看marc_s的代码,这是你应该做的

我也发现这非常令人沮丧,我无法理解这个问题。虽然很多答案都是正确的,但有一行很简单,经常被我和其他人忽略,即命令需要是存储过程,而不仅仅是带参数的sql,所以我希望这能有所帮助:

           cmd.CommandType = CommandType.StoredProcedure;

cmd.Txt应该像这样:

           @"my_stored_proct "

           @"my_stored_proct @p1, @p2, @p3 out"

所以把它们放在一起。你可能想把它分成几个方法。并添加超时等。然而,这些是我认为与其他没有输出参数的命令不同的关键部分。

      using (SqlCommand cmd= new SqlCommand())
      {
           cmd.Text= ...;
           cmd.CommandType = CommandType.StoredProcedure;
           SqlParameter outParam = cmd.Parameters.Add("@guidid", SqlDbType.Uniqueidentifier);
           outParam.Direction = ParameterDirection.Output;
           using (var connection = new SqlConnection(this.myConnectionString))
           {
            connection.Open();
            cmd.Connection = connection;
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch
            {
             //    put your sql catches etc. here..
              throw;
            }  
          }  
       var outValue = outParam.Value; 
       //query outValue e.g. ToString()   
       }