Accessの深淵:DDL操作と「原子性」の脆き境界線を制御する
Access VBAを扱う多くの開発者が、`TableDef`や`Field`オブジェクトを弄る際、致命的な誤解をしている。それは「VBAのコードが走れば、データベースの状態も安泰である」という盲信だ。
AccessのDDL(データ定義言語)操作、つまり`TableDefs.Append`や`Fields.Delete`といった処理は、DML(データ操作言語)とは異なり、DAOの`BeginTrans` / `CommitTrans` の保護下にない。これが何を意味するか? 処理の途中でエラーが発生し、プログラムが中断した瞬間、あなたのデータベースは「中途半端に定義が書き換わったゾンビ状態」に陥るということだ。
本稿では、レガシーかつミッションクリティカルな環境で生き抜くための、テーブル定義変更における「原子性(Atomicity)」の担保手法を伝授する。
—
1. なぜDAOのトランザクションではDDLを守れないのか
標準的なDAOの`BeginTrans`は、あくまで「レコードの更新・追加・削除」というデータ層の変更を管理する。テーブル構造のメタデータ変更は、データベースエンジン(ACE/JET)のカタログ領域に直接書き込まれるため、トランザクションのロールバック対象外となる。
これを回避し、物理的なスキーマ変更を「失敗したらなかったことにする」には、「カレントデータベースの構造変更を制御する、外部の防波堤」を構築する必要がある。
—
2. 実践:スキーマ変更の安全なトランザクション設計
我々が取るべき戦略は「バックアップ・インスタンスを用いたスワップ」か「変更ログの生成と逆変換処理」である。ここでは、現場で最もコストパフォーマンスが高い「実行順序とエラーハンドラによる完全復旧」の設計パターンを示す。
‘ スキーマ変更を安全に実行するための設計パターン
Public Sub SafeTableModify()
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim fld As DAO.Field
Dim blnChanged As Boolean
Set db = CurrentDb
On Error GoTo ErrorHandler
‘ 1. オブジェクトの明示的参照とロック確認
Set tdf = db.TableDefs(“m_MasterData”)
‘ 2. 変更処理の開始
blnChanged = False
‘ フィールド追加のDDL実行
db.Execute “ALTER TABLE m_MasterData ADD COLUMN UpdateLog TEXT(255)”, dbFailOnError
blnChanged = True
‘ ここでさらなる複雑な制約追加を行う想定…
Exit Sub
ErrorHandler:
‘ 致命的なエラー発生時のリカバリ
If blnChanged Then
‘ 変更が適用済みであれば、逆操作(ロールバック用DDL)を実行
db.Execute “ALTER TABLE m_MasterData DROP COLUMN UpdateLog”, dbFailOnError
End If
‘ メモリ最適化とリソース解放
Set fld = Nothing
Set tdf = Nothing
Set db = Nothing
Err.Raise Err.Number, “SafeTableModify”, “スキーマ変更に失敗しました。ロールバックを実行しました。”
End Sub
極限の知見:メモリ最適化の真実
`Set db = Nothing` を書くだけで満足してはならない。AccessのCOMオブジェクトは、参照カウントが残っている限りメモリを食いつぶす。特にスキーマ変更時は、`db.TableDefs.Refresh` を呼び出すタイミングが重要だ。これを怠ると、キャッシュされた古い定義を参照し続け、整合性が取れなくなる。
—
3. シニアエンジニアが意識すべき「Windows API」との連携
大規模な社内システムでは、DDL実行時に排他制御が甘いと即座に「ファイルロック」で落ちる。これを未然に防ぐため、処理開始前にAPIを用いて、自分以外のプロセスが当該データベースに接続していないか確認する手法が推奨される。
`GetFileAttributes`や`CreateFile` APIを使い、排他モードでのオープンを試みることで、DDL発行前に「安全な環境」を確保する。
- 極意: `DBEngine.Idle dbRefreshCache` を活用せよ。DDL実行直後にこれを叩くことで、データベースエンジン内部のページバッファを強制的に同期させ、後続の処理での「型不一致」や「オブジェクト未定義」エラーを極限まで減らせる。
—
4. 最後に:レガシーシステムとの付き合い方
Access VBAは「腐ったレガシー」などではない。正しく制御すれば、これほど高速にプロトタイピングから実運用までを完結できるツールはない。
DDLの変更は、手術である。メスを入れる前に、必ず「元に戻すための準備」を済ませる。そして、エラー発生時に「綺麗に掃除をして立ち去る」こと。この「外科医のような規律」こそが、伝説的なエンジニアと、ただコードを書くプログラマの決定的な差だ。
次のメンテ時、あなたが修正したテーブル定義が、静寂の中で完璧に機能していることを願う。健闘を祈る。
