2014/07/05

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

レコードを更新してみる。わかってしまえば難しいことではないけど、Access らしい動作かなと。
UPDATE Table_1 SET Table_1.F_Num = 999, Table_1.F_Text = "ABC"
WHERE Table_1.ID In (10,11);
SQLExecDirect: SELECT "dbo"."Table_1"."ID" FROM "dbo"."Table_1" WHERE ("ID" IN (10 ,11 ) ) 
SQLPrepare: SELECT "ID","F_Num","F_Text"  FROM "dbo"."Table_1"  WHERE "ID" = ?
SQLExecute: (GOTO BOOKMARK)
SQLPrepare: UPDATE "dbo"."Table_1" SET "F_Num"=?,"F_Text"=? WHERE "ID" = ?
SQLExecute: (UPDATE)
SQLExecute: (GOTO BOOKMARK)
SQLExecute: (UPDATE)
ここで実施されているのは、
1行目:抽出条件にマッチするレコードの主キーの取得
2行目:主キーをパラメータとするクエリの準備
3行目:準備されたクエリで1レコードフェッチ
4行目:更新用 SQLの準備
5行目:更新
6行目:準備されたクエリで1レコードフェッチ
7行目:更新
2行目の前にトランザクション開始、対象の更新完了後トランザクションcommit or rollback

Access で テーブルを開いたとき、更新可能な クエリを開いたとき、レコードソース が設定されたフォームを開いたとき、要は ダイナセット タイプの レコードセット を使用し レコード を更新する場合は異なる動作をする。この時のログは次の通り。
SQLExecute: (GOTO BOOKMARK)
SQLExecDirect: UPDATE "dbo"."Table_1" SET "F_Num"=?,"F_Date"=?,"F_Text"=?  WHERE "ID" = ? AND "F_Num" = ? AND "F_Date" = ? AND "F_Text" = ?
1行目:
主キーを条件にした カレントレコード を フェッチ
表示されているレコードは"最新"であるとは限らないから、ここで確認される
レコードの編集しようとしたとき、表示が更新されることがあるのがこの時の動作
2行目:
直前にトランザクション begin
主キーとフィールド の取得済みオリジナル値を条件にした更新
なぜなら、編集中にレコードが更新されている可能性があるから
直後にトランザクション commit or rollback

さて、フィールドのオリジナル値を条件にしているのだけど、これは効率的ではないことが多いはず。なので、SQL Server 上のテーブルには rowversion 列を用意する。
CREATE TABLE [dbo].[Table_1](
 [ID] [int] IDENTITY(1,1) NOT NULL,
 [F_Num] [int] NULL,
 [F_Date] [date] NULL,
 [F_Text] [nvarchar](10) NULL,
 [F_TS] [timestamp] NOT NULL
 CONSTRAINT [PK_Table_1]
 PRIMARY KEY CLUSTERED ([ID] ASC) ON [PRIMARY]
)
ODBC データソース である SQL Server の テーブル に TIMESTAMP 列がある場合、ACE はこれを使うようになる。
SQLExecute: (GOTO BOOKMARK)
SQLExecDirect: UPDATE "dbo"."Table_1" SET "F_Num"=?  WHERE "ID" = ? AND "F_TS" = ?
SQLExecute: (GOTO BOOKMARK)
1行目:
主キーを条件にした カレントレコード を フェッチ
2行目:
直前にトランザクション begin
主キーとrowversion値を条件にした更新
なぜなら、編集中にレコードが更新されている可能性があるから
直後にトランザクション commit or rollback
3行目:
rowversion 値が更新されているはずだから、主キーを条件にした カレントレコード を フェッチ

0 件のコメント: