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