1

ODBC接続を介して複数のSQLクエリを実行するインターフェイスがあります。

これらのクエリは、関数の作成、ストアドプロシージャ、ストアドプロシージャの実行などを行います。

それらの1つが失敗した場合は、完全なロールバックを開始したいと思います。

現時点ではコミットが実行されないため、最後にabegin transactionとaをクエリする単純な計画では、のcommit transaction後にランタイムエラーが発生します。begin transaction

一連のクエリの周りにトランザクションブロックを配置する可能性はありますか?

4

1 に答える 1

3

はい、できます。Insert または Update の種類の SQL ステートメントを作成するつもりだと思います (select クエリではありません)。この種のアクションを行う前に、クエリ間で設定した新しいデータと関係がない場合にのみ、単一のトランザクションでクエリを実行することを忘れないでください。これは、新しいデータがまだコミットされていないため、次のステートメントで is を使用できないためです。

これは、トランザクションを使用して一連のコマンドを実行するコードです。

    /// <summary>
    /// Execute commands with an open SQL connection.
    /// Note: To execute a stored procedure send to useTransaction parameter false value
    /// </summary>
    /// <param name="connection">An opened SqlConnection</param>
    /// <param name="commands">A string array of the requested commands to execute</param>
    /// <param name="useTransaction">true if to force transaction, false to execute the commands without transaction</param>
    /// <returns>true for success, otherwise false</returns>
    public static bool ExecuteSqlCommands(SqlConnection connection, string[] commands, bool useTransaction)
    {
        bool bStatus = false;

        string[] lines = commands; // regex.Split(sql);

        SqlTransaction transaction = null;
        if (useTransaction)
            transaction = connection.BeginTransaction();
        using (SqlCommand cmd = connection.CreateCommand())
        {
            cmd.Connection = connection;
            if (useTransaction)
                cmd.Transaction = transaction;

            foreach (string line in lines)
            {
                if (line.Length > 0)
                {
                    cmd.CommandText = line;
                    cmd.CommandType = CommandType.Text;

                    try
                    {
                        cmd.ExecuteNonQuery();
                    }
                    catch (SqlException e)
                    {
                        string msg = e.Message;
                        if (useTransaction)
                            transaction.Rollback();
                        throw;
                    }
                }
            }
            bStatus = true;
        }
        if (bStatus && useTransaction)
            transaction.Commit();

        return bStatus;
    }
于 2012-11-22T14:28:09.723 に答える