
トランザクション
oo4o(Oracle Objects for OLE)でもトランザクション(transaction)は使えます。
ちなみにトランザクションとは、確定(コミット)前であれば、DML文(Insert、Update、Delete)の実行を取り消す(ロールバック)ことが出来る処理のことです。
もう少し細かく言うと、処理の一貫性をを保つもので、処理が完全に終了するか、まったく実行されない状態にするかの、どちらかの結果になることを保証するものです。
まぁ、システム屋で「トランザクションって何?」って人に出会ったことが無いので、説明は不要ですよね?
ともあれ、今回はこれを試してみます。
サンプルソース
内容は前回とほとんど同じです。
トランザクションを制御する処理と、エラートラップの追加だけです。
' データ登録サンプル(CreateSQL:トランザクション)
'
Sub insertTestCreateSQLTransaction()
On Error GoTo systemError
'--------------
' 変数宣言
'--------------
'SQL文
Dim mySql As String
'登録データ
Dim myTbl(2, 1) As String '登録用データ配列
Dim myInd As Integer 'カウンタ
'oo4o用のオブジェクト
Dim OO4OSession As Object
Dim EmpDb As Object
Dim sqlStatement As Object
'-----------------
' 初期処理
'-----------------
'INSERT文作成
mySql = ""
mySql = mySql & " INSERT INTO"
mySql = mySql & " TESTDB (TESTSTR,TESTNUM)"
mySql = mySql & " VALUES (:ADDSTR, :ADDNUM)"
'登録用のデータ作成
myTbl(0, 0) = "A": myTbl(0, 1) = 1
myTbl(1, 0) = "B": myTbl(1, 1) = 2
myTbl(2, 0) = "C": myTbl(2, 1) = 3
'-----------------
' DB接続
'-----------------
'更新用のDB接続
Set OO4OSession = CreateObject("OracleInProcServer.XOraSession")
Set EmpDb = OO4OSession.OpenDatabase(ORA_DBSTRING, ORA_USERNAME & "/" & ORA_PASSWD, 0&)
'バインド変数の設定
EmpDb.Parameters.Add "ADDSTR", CStr(myTbl(0, 0)), 1
EmpDb.Parameters("ADDSTR").ServerType = 1 'ORATYPE_VARCHAR2
EmpDb.Parameters.Add "ADDNUM", CInt(myTbl(0, 1)), 1
EmpDb.Parameters("ADDNUM").ServerType = 2 'ORATYPE_NUMBER
'-----------------
' データ登録
'-----------------
'トランザクションを開始します。
EmpDb.BeginTrans
'Insert文の実行(1件目)
Set sqlStatement = EmpDb.CreateSQL(mySql, &H2&)
'Insert文の実行(2件目以降)
For myInd = 1 To UBound(myTbl)
'バインド変数の再設定
EmpDb.Parameters("ADDSTR").Value = CStr(myTbl(myInd, 0))
EmpDb.Parameters("ADDNUM").Value = CInt(myTbl(myInd, 1))
'Insert文を実行
sqlStatement.Refresh
Next
'-----------------
' 終了処理
'-----------------
'正常終了
normalEnd:
'コミットします。
EmpDb.CommitTrans
'終了メッセージの表示
MsgBox "正常終了!" & Chr(10) & Chr(10) & "登録件数:" & sqlStatement.RecordCount
'オブジェクトの開放
Set sqlStatement = Nothing
Set EmpDb = Nothing
Set OO4OSession = Nothing
'終了
Exit Sub
'異常終了
systemError:
'エラーメッセージ表示てからエラーをクリア。
If Not Err.Number = 0 Then MsgBox (Err.Number & ", " & Err.Description)
Err.Clear
'エラートラップを無効にします。
On Error GoTo 0
'ロールバックします。
EmpDb.Rollback
'オブジェクトを開放します。
Set sqlStatement = Nothing
Set EmpDb = Nothing
Set OO4OSession = Nothing
End Sub
ソース説明
1. トランザクションの開始
トランザクションは、OraDatabaseオブジェクトのBeginTransメソッドを使用することで開始されます。
(OraSessionオブジェクト、OraConnectionオブジェクトでも使えます)
このメソッドを実行すると、その後の実行しているInsert文はコミットされるまでDBに反映されません。
2. トランザクションの終了(正常時)
コミットは、CommitTransメソッドで実行することが出来ます。
このメソッドを実行することで、発行したInsert文が確定されて、トランザクションが終了します。
3. トランザクションの終了(異常時)
処理が異常終了した場合、実行したInsert文をキャンセルするためにロールバックを実行します。
これは、Rollbackメソッドで実行します
このメソッドを実行することで、発行したInsert文が取り消されて、トランザクションが終了します。
ちなみに、エラートラップを「On Error GoTo systemError」で実現しているため、トランザクションの開始前(BeginTransメソッドの発効前)にエラー処理が実行されることがあります。
トランザクションが開始されていない状態でRollbackメソッドを実行するとエラーが発生することがあるので、直前に「On Error GoTo 0」でエラートラップを無効可しています。
考察
なんか、わかっている人のための記述になっちゃいましたね。
(まぁ、一種の備忘録なので、これはこれで良いんですが)
2年くらい前に、データベーススペシャリストを受験した時に、真剣に勉強したことがあるので、詳しく書けないこともないかも知れませんが、なんか理論に偏っちゃいそうなんですよね。
こんなブログで、教科書みたいなこと書いても面白くないので、サンプルだけにしときました。
おまけ
oo4oでのトランザクションの実行方法は、他にもあるので紹介しておきます。
もっとも、正攻法とは言えないのでお勧めしませんが...。
1. トランザクションの開始
OraDatabaseオブジェクトの、AutoCommitプロパティというのが、コミットのタイミングを制御しています。
これは、boolean型でTrueであれば、自動的にコミットされ、Falseであれば、トランザクション制御をしないとコミットされなくなります。
つまり、サンプル中の「EmpDb.BeginTrans」は「EmpDb.AutoCommit = False」に書き換えることが出来ます。
2. コミット
サンプルでは、CommitTransメソッドを使用していますが、SQLで直接コミットを実行しても問題なく動作します。
サンプルの「EmpDb.CommitTrans」は「EmpDb.ExecuteSQL ("commit")」に書き換えられます。
3. ロールバック
ロールバックも同様に、「EmpDb.Rollback」を「EmpDb.ExecuteSQL ("rollback")」に書き換え可能です。
4. その他
コミットとロールバックは、CreateSQLメソッドを使用してもokです。
コミットであれば、こんな感じです。
Dim sqlTran As Object
Set sqlTran = EmpDb.CreateSQL("commit", &H2&)
まぁ、戻値を受け取るオブジェクトが増えるので、あえて使う理由は思いつきませんが...
前回:oo4oでExcelから登録してみた(CreateSQL)
投稿記事の一覧:目次
--- blog end ---
スポンサードリンク


