2014/08/12

Access 2013 ODBC リンク テーブル と SQL Server - 11

さて、Recordset オブジェクト (DAO) です。Database.OpenRecordset メソッド (DAO)で Recordset を取得する。まずは、テーブル定義。都合がよいときもあるので rowversion (Transact-SQL)を持たせている。
CREATE TABLE Table_0(
  ID     int IDENTITY(1,1)
 ,F_Num  int
 ,F_Date date
 ,F_TS   rowversion
 CONSTRAINT PK_Table_0 PRIMARY KEY CLUSTERED (ID ASC)
)
この時、こんな感じでRecordsetを取り扱う。
Sub DAORecordset_Dynaset()
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset( _
                "SELECT ID, F_Num FROM Table_0" _
              , DAO.RecordsetTypeEnum.dbOpenDynaset _
              , DAO.RecordsetOptionEnum.dbSeeChanges _
              )
End Sub
レコードの更新/削除が可能。また、フィールドに主キーが含まれているから、レコードの追加が可能。なければ追加できない。OpenRecordset メソッドが実行された時、
SQLExecDirect: SELECT "dbo"."Table_0"."ID" FROM "dbo"."Table_0" 
SQLPrepare: SELECT "ID","F_Num","F_TS"  FROM "dbo"."Table_0"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLExecute: (GOTO BOOKMARK)
最初に主キーのみ取得する。条件があれば条件に該当する主キーのみ取得。その主キーを利用してレコードを取得する。該当するレコードがあれば先頭のレコードのみ取得まで。該当する他のレコードをすぐさま取得しないことと rowversion のフィールドを自動的に取得することがポイント。

Sub DAORecordset_Snapshot()
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset( _
                "SELECT F_Num FROM Table_0 WHERE ID < 100" _
              , DAO.RecordsetTypeEnum.dbOpenSnapshot _
              )
End Sub
SQLExecDirect: SELECT "F_Num"  FROM "dbo"."Table_0" WHERE ("ID" < 100 ) 
Recordset が スナップショットタイプである時、条件に該当するレコードすべてを取得する。
Sub DAORecordset_AppendOnly()
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset( _
                "Table_0" _
              , DAO.RecordsetTypeEnum.dbOpenDynaset _
              , DAO.RecordsetOptionEnum.dbSeeChanges _
              + DAO.RecordsetOptionEnum.dbAppendOnly _
              )
End Sub
RecordsetのオプションがdbAppendOnly 追加のみであるとき、レコードの操作(追加/更新)されるまでなにも発生しない。

おまけで、ODBC リンク テーブルがない場合、
Sub DAORecordset_woLinkTable1()
    Dim dbs As DAO.Database, rs As DAO.Recordset
    Set dbs = DBEngine.OpenDatabase("", False, False, cnStr)
    Set rs = dbs.OpenRecordset( _
                "SELECT ID, F_Num FROM Table_1" _
              , DAO.RecordsetTypeEnum.dbOpenDynaset _
              , DAO.RecordsetOptionEnum.dbSeeChanges _
              )
    dbs.Close
End Sub

Sub DAORecordset_wolinkTable2()
    Dim dbs As DAO.Database, rs As DAO.Recordset
    Set dbs = DBEngine.OpenDatabase("", False, False, cnStr)
    Set rs = dbs.OpenRecordset( _
                "SELECT db_name()" _
              , DAO.RecordsetTypeEnum.dbOpenSnapshot _
              , DAO.RecordsetOptionEnum.dbSQLPassThrough _
              )
    dbs.Close
End Sub

0 件のコメント: