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

我有一个存储过程:

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 ) 

我需要C#中的id并将其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()); 

但它不会返回任何东西

首先 – 如果它是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 uniqueidentifier输出设置为输出参数? 这意味着一旦执行存储过程,它将覆盖它。 如果这是你的意图,那么你需要在insert语句之后添加一个语句,将输出参数设置为你想要的值。 像这样:选择@guidid = @generatedID。 是的看看marc_s代码,这就是你应该这样做的方式。

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

  cmd.CommandType = CommandType.StoredProcedure; 

cmd.Txt应如下所示:

  @"my_stored_proct " 

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

所以把它们放在一起。 您可能希望将其分成几种方法。 并添加TimeOuts等。但是,我认为这些是与输出参数的其他命令不同的关键部分。

  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 eg ToString() }