繁体   English   中英

在C#中使用SqlTransaction,如何从存储过程中获取输出参数并插入到另一个表中?

[英]Using SqlTransaction in C#, how to get an output parameter from a stored procedure and insert into another table?

我有两个表:Table1 和 Table2。 我需要新插入的 Id(来自Table1 )作为应该插入Table2的输出参数。 我必须在这里使用SqlTransactionTransactionScope

存储过程:

    CREATE PROC InsertTable1
    (
        @Name nvarchar(50),
        @OutputParam int out
    )
    AS
    BEGIN
        INSERT INTO Table1(Name) 
        VALUES(@Name)

        SELECT @OutputParam = SCOPE_IDENTITY() 
    END

C#代码:

SqlTransaction transaction = db.sqlconn.BeginTransaction();

SqlParameter[] param = new SqlParameter[2];
param[0] = new SqlParameter("@Name", "TestName");
param[1] = new SqlParameter("@OutputParam", SqlDbType.Int);
param[1].Direction = ParameterDirection.Output;

SqlHelper.ExecuteNonQuery(transaction, "InsertTable1", param);

int outputId = (int)param[1].Value;

当我运行和调试项目时出现错误

未将对象引用设置为对象的实例

就在执行之后

int outputId = (int)param[1].Value;

我认为交易正在关闭连接或其他什么。 如果我不使用事务,它会起作用。 但无论如何我都必须使用事务。 我愿意接受任何替代方法来实现相同的结果。

有关事务的问题,请查看 TransactionScope 类。 这是微软文档的介绍部分。

TransactionScope 类提供了一种将代码块标记为参与事务的简单方法,而无需您与事务本身进行交互。 事务范围可以自动选择和管理环境事务。 由于其易用性和效率,建议您在开发事务应用程序时使用 TransactionScope 类。

您还可以使用事务属性( TransactionInformationCurrent )在调试时调查事务状态。 这是我现在能想到的所有尚未提出的建议。

首先,您正在使用的SqlHelper.ExecuteNonQuery的重载采用参数数组,而不是SqlParameter数组。 它只能编译和运行,因为类型是object 因此,它将通过SqlCommandBuilder派生自己的参数,并尝试从您的 param 参数中设置它们的值,但当然 SqlParameter 不能将 SqlParameter 作为其.Value 然而,这一点没有实际意义,因为对源代码的评论(下面)特别指出您无法从此方法访问 OUTPUT 或 RETURN 值。

    /// <summary>
    /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified 
    /// SqlTransaction using the provided parameter values.  This method will query the database to discover the parameters for the 
    /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order.
    /// </summary>
    /// <remarks>
    /// This method provides no access to output parameters or the stored procedure's return value parameter.
    /// 
    /// e.g.:  
    ///  int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36);
    /// </remarks>
    /// <param name="transaction">a valid SqlTransaction</param>
    /// <param name="spName">the name of the stored procedure</param>
    /// <param name="parameterValues">an array of objects to be assigned as the input values of the stored procedure</param>
    /// <returns>an int representing the number of rows affected by the command</returns>
    public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues)
    {
        //if we receive parameter values, we need to figure out where they go
        if ((parameterValues != null) && (parameterValues.Length > 0))
        {
            //pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache)
            SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection.ConnectionString, spName);

            //assign the provided values to these parameters based on parameter order
            AssignParameterValues(commandParameters, parameterValues);

            //call the overload that takes an array of SqlParameters
            return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters);
        }
        //otherwise we can just call the SP without params
        else
        {
            return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName);
        }
    }

USE OUTPUT子句获取插入的数据并保存到临时表中。

从存储过程返回该数据

您不需要在输出中获取值,如果您想在另一个表中插入数据,在存储过程中,您可以轻松编写另一个插入查询,将这个 id 插入另一个表中

我可以看到您正在使用自定义 SqlHelper.ExecuteNonQuery 方法来执行查询,能否请您分享 SqlHelper.ExecuteNonQuery 方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM