在C#中使用存储过程输出参数
我有一个问题,从Sql Server存储过程返回一个输出参数到一个C#variables。 我已经阅读了其他文章,不仅在这里,而且在其他网站上,我不能得到它的工作。 这是我目前有的。 目前我只是试图打印回来的价值。 以下代码返回一个空值。 我试图返回的是主键。 我曾尝试使用@@IDENTITY
和SCOPE_INDENTITY()
(即SET @NewId = SCOPE_IDENTITY()
)。
存储过程:
CREATE PROCEDURE usp_InsertContract @ContractNumber varchar(7), @NewId int OUTPUT AS BEGIN INSERT into [dbo].[Contracts] (ContractNumber) VALUES (@ContractNumber) Select @NewId = Id From [dbo].[Contracts] where ContractNumber = @ContractNumber END
打开数据库:
pvConnectionString = "Server = Desktop-PC\\SQLEXPRESS; Database = PVDatabase; User ID = sa; PASSWORD = *******; Trusted_Connection = True;"; try { pvConnection = new SqlConnection(pvConnectionString); pvConnection.Open(); } catch (Exception e) { databaseError = true; }
执行命令:
pvCommand = new SqlCommand("usp_InsertContract", pvConnection); pvCommand.Transaction = pvTransaction; pvCommand.CommandType = CommandType.StoredProcedure; pvCommand.Parameters.Clear(); pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber)); SqlParameter pvNewId = new SqlParameter(); pvNewId.ParameterName = "@NewId"; pvNewId.DbType = DbType.Int32; pvNewId.Direction = ParameterDirection.Output; pvCommand.Parameters.Add(pvNewId); try { sqlRows = pvCommand.ExecuteNonQuery(); if (sqlRows > 0) Debug.Print("New Id Inserted = ", pvCommand.Parameters["@NewId"].Value.ToString()); } catch (Exception e) { Debug.Print("Insert Exception Type: {0}", e.GetType()); Debug.Print(" Message: {0}", e.Message); } }
我稍微修改了你的存储过程(使用SCOPE_IDENTITY
),它看起来像这样:
CREATE PROCEDURE usp_InsertContract @ContractNumber varchar(7), @NewId int OUTPUT AS BEGIN INSERT INTO [dbo].[Contracts] (ContractNumber) VALUES (@ContractNumber) SELECT @NewId = SCOPE_IDENTITY() END
我试过这个,它工作得很好(与修改后的存储过程):
// define connection and command, in using blocks to ensure disposal using(SqlConnection conn = new SqlConnection(pvConnectionString )) using(SqlCommand cmd = new SqlCommand("dbo.usp_InsertContract", conn)) { cmd.CommandType = CommandType.StoredProcedure; // set up the parameters cmd.Parameters.Add("@ContractNumber", SqlDbType.VarChar, 7); cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output; // set parameter values cmd.Parameters["@ContractNumber"].Value = contractNumber; // open connection and execute stored procedure conn.Open(); cmd.ExecuteNonQuery(); // read output value from @NewId int contractID = Convert.ToInt32(cmd.Parameters["@NewId"].Value); conn.Close(); }
这也能在你的环境中工作吗? 我不能说为什么你原来的代码将无法正常工作 – 但是当我在这里这样做,VS2010和SQL Server 2008 R2,它只是完美的工作….
如果你没有得到一个值 – 那么我怀疑你的表Contracts
可能没有一个具有IDENTITY
属性的列。
在更改存储过程之前,请检查您当前的输出是什么。 在SQL Server Management中运行以下命令:
DECLARE @NewId int EXEC @return_value = [dbo].[usp_InsertContract] N'Gary', @NewId OUTPUT SELECT @NewId
看看它返回。 这可能会给你一些提示,为什么你的参数没有被填充。
存储过程………
CREATE PROCEDURE usp_InsertContract @ContractNumber varchar(7) AS BEGIN INSERT into [dbo].[Contracts] (ContractNumber) VALUES (@ContractNumber) SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY] END
C#
pvCommand.CommandType = CommandType.StoredProcedure; pvCommand.Parameters.Clear(); pvCommand.Parameters.Add(new SqlParameter("@ContractNumber", contractNumber)); object uniqueId; int id; try { uniqueId = pvCommand.ExecuteScalar(); id = Convert.ToInt32(uniqueId); } catch (Exception e) { Debug.Print(" Message: {0}", e.Message); } }
编辑: “我仍然得到一个DBNull值….对象不能从DBNULL转换到其他types,明天我会再次采取这种做法,我要去我的其他工作,”
我相信你的SQL表中的Id列不是一个标识列。
在您的C#代码中,您正在使用该命令的事务。 只需提交事务,然后访问您的参数值,您将获得该值。 为我工作。 🙂