zukucode
主にWEB関連の情報を技術メモとして発信しています。

VB.NET ODP.NETでトランザクションを実行する

ODP.NETを使用してSQLを実行する際にトランザクションを実行する方法を紹介します。

以下はTABLE_ATABLE_Bを更新している処理です。

この処理にトランザクションを実行して、エラー時は全てロールバックできるようにします。

(以下はわかりやすくするため1つのファンクションで実行していますがSQLごとにファンクション化する方法を記事の最後で紹介しています)

Imports Oracle.DataAccess.Client 'ファイルの先頭に追加

Public Sub SelectData(id As String)

    Dim ds As New DataSet

    Using conn As OracleConnection = New OracleConnection(接続文字列)

        'コネクションOpen
        conn.Open()

        Dim sql As StringBuilder

        'TABLE_Aを更新
        sql = New StringBuilder
        sql.AppendLine(" UPDATE TABLE_A ")
        sql.AppendLine(" SET ")
        sql.AppendLine("    T1.COL1 = :COL1 ")

        Using cmd As New OracleCommand(sql.ToString(), conn)
            cmd.BindByName = True
            cmd.Parameters.Add(":COL1", OracleDbType.Decimal).Value = id

            cmd.ExecuteNonQuery()
        End Using

        'TABLE_Bを更新
        sql = New StringBuilder
        sql.AppendLine(" UPDATE TABLE_B")
        sql.AppendLine(" SET ")
        sql.AppendLine("    T1.COL1 = :COL1 ")

        Using cmd As New OracleCommand(sql.ToString(), conn)
            cmd.BindByName = True
            cmd.Parameters.Add(":COL1", OracleDbType.Decimal).Value = id

            cmd.ExecuteNonQuery()
        End Using

    End Using

End Sub

以下のように、トランザクションとして実行したいSQLの処理をUsingで囲みます。

また、処理の最後にコミットを実行する処理を追加しています。

エラーが発生した場合はコミットが実行されないため、トランザクションはロールバックされます。(ロールバック処理を明示的に記載する必要はありません)

Imports Oracle.DataAccess.Client 'ファイルの先頭に追加

Public Sub SelectData(id As String)

    Dim ds As New DataSet

    Using conn As OracleConnection = New OracleConnection(接続文字列)

        'コネクションOpen
        conn.Open()

        Using trans As OracleTransaction = conn.BeginTransaction() 'トランザクション開始

            Dim sql As StringBuilder

            'TABLE_Aを更新
            sql = New StringBuilder
            sql.AppendLine(" UPDATE TABLE_A ")
            sql.AppendLine(" SET ")
            sql.AppendLine("    T1.COL1 = :COL1 ")

            Using cmd As New OracleCommand(sql.ToString(), conn)
                cmd.BindByName = True
                cmd.Parameters.Add(":COL1", OracleDbType.Decimal).Value = id

                cmd.ExecuteNonQuery()
            End Using

            'TABLE_Bを更新
            sql = New StringBuilder
            sql.AppendLine(" UPDATE TABLE_B")
            sql.AppendLine(" SET ")
            sql.AppendLine("    T1.COL1 = :COL1 ")

            Using cmd As New OracleCommand(sql.ToString(), conn)
                cmd.BindByName = True
                cmd.Parameters.Add(":COL1", OracleDbType.Decimal).Value = id

                cmd.ExecuteNonQuery()
            End Using

            trans.Commit() 'コミット
        End Using
    End Using

End Sub

排他制御など、処理結果によって明示的にロールバックをしたい場合は以下のようにします。

If result = True Then
    '正常終了時はコミット
    trans.Commit()
Else
    'エラー時はロールバック
    trans.Rollback()
End If

SQLごとにファンクション化

長いSQL文を組み立てる必要がある場合があると、ファンクションが長くなりがちですので、実行するSQLごとにファンクションを作成して、処理を見やすくします。

Imports Oracle.DataAccess.Client 'ファイルの先頭に追加

Public Sub SelectData(id As String)

    Dim ds As New DataSet

    Using conn As OracleConnection = New OracleConnection(接続文字列)

        'コネクションOpen
        conn.Open()

        Using trans As OracleTransaction = conn.BeginTransaction() 'トランザクション開始

            Dim sql As StringBuilder

            'TABLE_Aを更新
            UpdateTABLE_A(conn, id)

            'TABLE_Bを更新
            UpdateTABLE_B(conn, id)

            trans.Commit() 'コミット
        End Using
    End Using

End Sub

Private Sub UpdateTABLE_A(ByVal conn As OracleConnection, id As String)

    Dim sql As StringBuilder

    'TABLE_Aを更新
    sql = New StringBuilder
    sql.AppendLine(" UPDATE TABLE_A ")
    sql.AppendLine(" SET ")
    sql.AppendLine("    T1.COL1 = :COL1 ")

    Using cmd As New OracleCommand(sql.ToString(), conn)
        cmd.BindByName = True
        cmd.Parameters.Add(":COL1", OracleDbType.Decimal).Value = id

        cmd.ExecuteNonQuery()
    End Using
End Sub

Private Sub UpdateTABLE_B(ByVal conn As OracleConnection, id As String)

    Dim sql As StringBuilder

    'TABLE_Bを更新
    sql = New StringBuilder
    sql.AppendLine(" UPDATE TABLE_B ")
    sql.AppendLine(" SET ")
    sql.AppendLine("    T1.COL1 = :COL1 ")

    Using cmd As New OracleCommand(sql.ToString(), conn)
        cmd.BindByName = True
        cmd.Parameters.Add(":COL1", OracleDbType.Decimal).Value = id

        cmd.ExecuteNonQuery()
    End Using
End Sub


関連記事

  • VB.NET YYYYMMDD形式の文字列を日付型に型変換する

    VB.NETでYYYYMMDD形式の文字列を日付型に型変換する方法を紹介します。最初にYYYY/MM/DDのように、年月日の区切りに/を追加します。/区切りの文字列にするとCDateで日付型に型変換で...


  • VB.NET YYYYMMDD書式の文字列が日付かどうか判定する

    VB.NETで、YYYYMMDD書式の文字列が日付として妥当かどうかを判定します。以下のように、Date.TryParseExactを使用して、日付型の文字列に変換可能かどうかで判定しています。Dat...


  • VB.NET 文字列の全角と半角の変換を行う

    VB.NETで文字列を全角→半角や半角→全角に変換するにはStrConv関数を使用します。StrConvの第1引数に対象文字列を指定し、第2引数に変換方法を指定します。


  • VB.NET TypeOfで変数の型判定・比較を行う

    VB.NETで変数の型をチェックするにはTypeOfを使用します。TypeOf チェックしたい変数名 Is 判定したい型の形式で指定します。


  • VB.NET StringBuilderの末尾の1文字を削除する

    StringBuilderで末尾の1文字だけ削除したいときは以下のようにします。位置の指定について、1文字目は0から始まるため、文字列の長さ(Length)-1の位置が末尾の位置となります。末尾の位置...


  • VB.NET 指定した文字列を削除する

    VB.NETで指定した文字列を削除する方法を紹介します。Replace関数は指定した文字列を別の文字列に置換する関数です。置換する文字列に空文字を指定すれば、指定した文字列が削除される形になります。J...


  • VB.NET 指定した桁数だけ同じ文字を文字列で定義する

    VB.NETで指定した桁数だけ同じ文字を文字列で定義する方法を紹介します。例えばオール9の10桁の文字列9999999999を定義するときに、9999999999を指定するのは、桁数を間違える危険があ...


  • VB.NET ダブルクォーテーションを文字列として扱う方法

    VB.NETで文字列を扱うときは以下のようにダブルクォーテーションで囲います。文字列の中にダブルクォーテーションを含めたい場合は少し工夫が必要です。以下のようにダブルクォーテーションを2つにすれば1つ...


  • VB.NET 文字列を数値に変換する方法

    VB.NETでString型の文字列を数値に変換する方法を紹介します。以下の例では、Integer型の数値に変換しています。文字列型の変数を数値型に変換する場合には以下に注意する必要があります。例えば...


  • VB.NET 文字列を連結する便利な方法まとめ

    VB.NETでは文字列の連結は文字列同士を&で結合できます。Visual Studio 2015からの新機能として文字列補間が可能になりました。以下のように、文字列の前に$をつけることにより、文字列の...