我在将输出参数从Sql Server存储过程返回到C#变量时遇到问题。我已经阅读了有关此内容的其他帖子,不仅在这里,而且在其他网站上,我无法让它工作。这是我现在拥有的。目前我只是想打印回来的价值。以下代码返回null值。我试图返回的是主键。我尝试过使用@@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);
}
}
答案 0 :(得分:109)
我稍微修改了你的存储过程(使用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
属性的列。
答案 1 :(得分:3)
在更改存储过程之前,请检查当前存储过程的输出。在SQL Server Management中运行以下命令:
DECLARE @NewId int
EXEC @return_value = [dbo].[usp_InsertContract]
N'Gary',
@NewId OUTPUT
SELECT @NewId
查看它返回的内容。这可能会给你一些提示,说明为什么你的外部参数没有被填满。
答案 2 :(得分:1)
存储过程.........
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转换为其他类型。明天我会再次接受这个。我已经离开了我的其他人工作,“
我认为SQL表中的Id列不是标识列。
答案 3 :(得分:0)
在您的C#代码中,您正在使用命令的事务。 只需提交事务,然后访问您的参数值,您将获得该值。 为我工作。 :)
答案 4 :(得分:0)
我遇到了类似的问题,先关闭了连接,然后读取参数,它工作正常。