2017-11-10

oo4oからADOへの変換 (3) Editメソッドとトランザクション

今回はトランザクションと行セット更新の例です。
サンプルコードは、Oracle® Objects for OLE開発者ガイドのBeginTransメソッド の例を書き換えたものです。

ADO
Sub Form_Load()
'Declare variables
' Dim OraSession As OraSession
' Dim OraDatabase As OraDatabase
Dim cnn As ADODB.Connection
' Dim OraDynaset As OraDynaset
Dim rst As ADODB.Recordset
' Dim fld As OraField
Dim fld As ADODB.Field
'Create the OraSession Object.
' Set OraSession = CreateObject("OracleInProcServer.XOraSession")
Set cnn = CreateObject("ADODB.Connection")
'Create the OraDatabase Object by opening a connection to Oracle.
' Set OraDatabase = OraSession.OpenDatabase("ExampleDb", "scott/tiger", 0&)
cnn.Open "Provider=OraOLEDB.Oracle;Data Source=ExampleDb;User ID=scott;Password=tiger"
Dim cmd As New ADODB.Command
cmd.ActiveConnection = cnn
cmd.CommandType = adCmdText
cmd.CommandText = "select * from emp"
'Create the OraDynaset Object.
' Set OraDynaset = OraDatabase.CreateDynaset("select * from emp", 0&)
Set rst = CreateObject("ADODB.Recordset")
rst.CursorLocation = adUseClient
rst.Open cmd, , adOpenStatic, adLockOptimistic
'Start Transaction processing.
' OraSession.BeginTrans
cnn.BeginTrans
'Setup a field object to save object references.
' Set fld = OraDynaset.Fields("sal")
Set fld = rst.Fields("sal")
'Traverse until EOF is reached, setting each employees salary to zero
' Do Until OraDynaset.EOF = True
Do Until rst.EOF = True
' OraDynaset.Edit
' fld.Value = 0
' OraDynaset.Update
' OraDynaset.MoveNext
fld.Value = 0
rst.Update
rst.MoveNext
' Loop
Loop
MsgBox "All salaries set to ZERO."
'Currently, the changes have NOT been committed to the database.
'End Transaction processing. Using RollbackTrans
'means the rollback can be canceled in the Validate event.
' OraSession.Rollback
cnn.RollbackTrans
'MsgBox "Salary changes rolled back."
End Sub
  • パラメータにも対応できるように、あえて Command オブジェクトを使用しています。
  • ADO では、編集開始の Edit メソッドが不要です。また、Update メソッドがなくてもMoveNext で更新されます。
  • oo4o の Rollback は、ADOでは RollbackTrans にメソッド名が変わります。BeginTrans, CommitTransはメソッド名も同じです。
  • ADO には、ResetTrans メソッドはないため、
On Error Resume Next
cn.RollbackTnans
On Error Goto 0

で代用することになります。

UpdateBatch メソッド(ADO)

ADO の場合、

rst.Open cmd, , adOpenStatic, adLockBatchOptimistic
Do Until rst.EOF = True
fld.Value = 0
rs.MoveNext
Loop
rst.UpdateBatch

Update をループの外に出し、UpdateBatch メソッドにすることにより、まとめて変更処理を行い、ラウンドトリップを削減できます。
MSDAORA で UpdateBatch メソッドを使う場合、Recordset の LockType に adLockBatchOptimistic を指定しなければ、

現在の Recordset は更新をサポートしていません。プロバイダーか、選択されたロックタイプの限界の可能性があります。

とのエラーが発生します。(OraOLEDB ではなぜか出ません。)

Execute メソッドによる更新可能行セットの取得(OraOLEDB)

OraOLEDBの場合、Command.Executeで更新可能な行セットを取得できます。

Set rst = CreateObject("ADODB.Recordset")
rst.Open cmd, , adOpenStatic, adLockOptimistic

の箇所は

cmd.Properties("IRowsetChange") = True
cmd.Properties("Updatability") = 7
Set rst = cmd.Execute

に書き換え可能です。
但し、AddNew メソッドを実行すると、

ORA-01400: (“SCOTT”.”EMP”.”EMPNO”)にはNULLは挿入できません。

が発生しました。

No comments:

Post a Comment