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