在C#中使用存储过程输出参数

Gar*_*ary 56 c# sql-server stored-procedures

我在将输出参数从Sql Server存储过程返回到C#变量时遇到问题.我已经阅读了有关此内容的其他帖子,不仅在这里,而且在其他网站上,我无法让它工作.这是我现在拥有的.目前我只是想打印回来的价值.以下代码返回null值.我试图返回的是主键.我尝试过使用@@IDENTITYSCOPE_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
Run Code Online (Sandbox Code Playgroud)

打开数据库:

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;
}
Run Code Online (Sandbox Code Playgroud)

执行命令:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

mar*_*c_s 119

我稍微修改了你的存储过程(使用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
Run Code Online (Sandbox Code Playgroud)

我尝试了这个,它工作得很好(使用修改后的存储过程):

// 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();
}
Run Code Online (Sandbox Code Playgroud)

这也适用于您的环境吗?我不能说为什么你的原始代码不起作用 - 但是当我在这里,VS2010和SQL Server 2008 R2这样做时,它只是完美无瑕....

如果你没有得到一个值 - 那么我怀疑你的表Contracts可能没有一个包含该IDENTITY属性的列.

  • 谢谢!感谢您抽出时间为我们这些人回答这段时间.:-) (7认同)
  • @ user3569147:**绝对不是!!**你应该看看[我们可以停止使用AddWithValue()吗?](http://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can- we-stop-using-addwithvalue-already /)并停止使用`.AddWithValue()` - 它可能导致意外和令人惊讶的结果...... (4认同)

Jer*_*son 1

存储过程.......

CREATE PROCEDURE usp_InsertContract
    @ContractNumber varchar(7)
AS
BEGIN

    INSERT into [dbo].[Contracts] (ContractNumber)
        VALUES (@ContractNumber)

    SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
END
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: “我仍然得到一个 DBNull 值....对象无法从 DBNull 转换为其他类型。明天我会再次处理这个问题。我要去做其他工作了,”

我相信 SQL 表中的 Id 列不是标识列。

在此输入图像描述