メイン画像

VBScript - SQL の代わりに Recordset を使ってデータを更新する

VBScript - SQL の代わりに Recordset を使ってデータを更新する


データの更新には一般的にINSERT文、UPDATE文、DELETE文といった SQL を使う。

しかし ADO の Recordset はデータの更新機能を持っているので、SQL を使わずにデータの更新ができる。

データの追加方法

AddNew でレコードセットにレコードを追加し、Update でテーブルに反映する。

Dim rst
Set rst = CreateObject("ADODB.Recordset")

'テーブル名を指定してレコードセットを開く
rst.Open "DEPT", _
         "Provider=OraOLEDB.Oracle;User ID=scott;Password=tiger;Data Source=ORCL;", _
         3, _
         3

'レコードを追加
rst.AddNew
rst.Fields("DEPTNO").Value = "50"
rst.Fields("DNAME").Value = "NEWDEPT"
rst.Fields("LOC").Value = ""

'変更を反映
rst.Update

 

変更をキャンセルしたいときは CancelUpdate を実行する。

rst.AddNew
rst.Fields("DEPTNO").Value = "50"
rst.Fields("DNAME").Value = "NEWDEPT"
rst.Fields("LOC").Value = ""

'変更をキャンセル
rst.CancelUpdate

 

Update も CancelUpdate もせずに Close するとエラーが起きる。

0x800a0c93 - ADODB.Recordset: このコンテキストで操作は許可されていません。

rst.AddNew
rst.Fields("DEPTNO").Value = "50"
rst.Fields("DNAME").Value = "NEWDEPT"
rst.Fields("LOC").Value = ""

'エラー発生
rst.Close

 

2レコードを一度に Update できるかと思ったが、AddNew を実行したタイミングで1レコード目がテーブルに反映された。

'1レコード目
rst.AddNew
rst.Fields("DEPTNO").Value = "51"
rst.Fields("DNAME").Value = "NEWDEPT-51"
rst.Fields("LOC").Value = "CAMBRIDGE"

'2レコード目
rst.AddNew                              '←の実行で上記のレコードが追加された
rst.Fields("DEPTNO").Value = "52"
rst.Fields("DNAME").Value = "NEWDEPT-52"
rst.Fields("LOC").Value = "BROOKLINE"

'テーブルに反映
rst.Update

 

レコードセットを開くとき、テーブル名ではなくクエリを指定してもよい。

rst.Open "select DEPTNO, DNAME, LOC from DEPT order by DEPTNO", _
         "Provider=OraOLEDB.Oracle;User ID=scott;Password=tiger;Data Source=ORCL;", _
         3, _
         3

データの更新方法

更新したいカラムの値を変更して Update を実行する。

レコードセットが複数件の場合、更新対象をループで探してから更新する。

次のように書くと、DEPTNO が “50” のレコードのカラム LOC を “QUINCY” に更新する。

rst.MoveFirst
Do While Not rst.EOF
  If rst.Fields("DEPTNO").Value = "50" Then
    rst.Fields("LOC").Value = "QUINCY"
    rst.Update
  End If

  rst.MoveNext
Loop

 

データ追加と同様に、変更をなかったことにするときは Update ではなく CancelUpdate を実行する。

データの削除方法

削除するレコードで Delete を実行する。

レコードセットが複数件の場合、削除対象をループで探してから削除する。

次のように書くと、DEPTNO が “50” のレコードを削除する。

rst.MoveFirst
Do While Not rst.EOF
  If rst.Fields("DEPTNO").Value = "50" Then
    rst.Delete
  End If

  rst.MoveNext
Loop

Recordset.LockType プロパティの設定

LockType プロパティは既定で 1:adLockReadOnly になる。
読み取り専用となりデータの変更ができないので別の値にしておく。

今回は 3:adLockOptimistic にした。
これはレコード単位の共有的ロックを表し、Update メソッドの呼び出し時(データの反映時)にのみレコードをロックする動きとなる。

ちなみに LockType が 1:adLockReadOnly のときに AddNew を呼び出すとエラーになる。

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

Recordset.CursorType プロパティの設定

CursorType プロパティがキーセットカーソル(1:adOpenKeyset)でも静的カーソル(3:adOpenStatic)でもない場合は、プログラムから AddNew で追加したレコードをそのプログラム内で参照/操作することができない。

既定値は前方スクロール カーソル(0:adOpenForwardOnly)なので、必要に応じて設定を変更しておく。

'レコードを追加
rst.AddNew
rst.Fields("DEPTNO").Value = "50"
rst.Fields("DNAME").Value = "NEWDEPT"
rst.Fields("LOC").Value = ""
rst.Update

'レコードセットのデータを全件表示
'  ★キーセットカーソル、または静的カーソルの場合のみ、上記で追加したレコードが表示される
rst.MoveFirst
Do While Not rst.EOF
  WScript.Echo rst.Fields("DEPTNO").Value & vbTab & rst.Fields("DNAME").Value & vbTab & rst.Fields("LOC").Value
  rst.MoveNext
Loop

アカウントを作成 して、もっと沢山の記事を読みませんか?


この記事が気に入ったら ことりと さんを応援しませんか?
メッセージを添えてチップを送ることができます。


この記事にコメントをしてみませんか?


酒とアクアリウムが最近の楽しみ。

おすすめの記事