内製のAccess 2003アプリを、DB部分はMariaDBに移行している。
フロントは.Net(C#)
ツールを使って工数を削減できないかと模索したが、以下のような正攻法で攻めるしかないと言う結論に達した。
- Access側のテーブルにて、極力Not Null制約を適用する... 後述のデータ移行クエリ実行の際、NullがあるとINSERT SELECT 文がこけるため、Nullの場合とそうで無い場合で別クエリを実行する必要が出てくるため。
文字列型は、NULL=空文字と考えて問題ない場合がほとんどと想定されるので、以下の手順を機械的に実行する。
文字列でない場合はNULLを置き換えるべき値が自明でない場合も多いので、一旦NULL値固定で移行し、列ごとに個別で移行(UPDATE DEST.COL=SRC.COL WHERE SRC.COL IS NOT NULL
)- 対象列の空文字を許可する。
- 該当列を更新する部分にてNULLの場合は空文字に置き換える処理を追加
- 画面のフォームがデータと連結していてSQLではなくDoCmdで処理している場合、後付でSQLを組み込むと競合エラーが面倒なので、単純にフォームの値をNz関数でNullを置換してやれば良い
- ウィザードに従って作成した画面などで、データ更新処理を明示的に記載されていない場合は、フォームの追加・更新前処理イベントにてNz関数を適用する
- UPDATE文で該当列のNULLを空文字に置換
- 該当列にNOT NULL制約を適用。
- MariaDB側に、同一レイアウトのテーブルを新規作成。参照制約も実装。
- MariaDBのODBCドライバをインストールし、対象のMariaDBをODBC登録。
- AccessのリンクテーブルとしてMariaDBのテーブルを登録
- AccessのテーブルからMariaDBのテーブルにデータを流し込む(INSERT SELECT)クエリを作成、初回の移行を行う。
参照整合性制約から、移行可能な順番がはっきりする。 - MariaDBのデータに対してアクセスするフロントプログラムを作成する。
- 移行後のテーブルレイアウトそのものでプログラムの動作検証が可能。
- フロントプログラムの作成が完了したら、MariaDBの全データをTruncateしてデータの本番移行を行う。
- データ移行の逆順で実行しても参照整合性制約からデータを削除できない場合がある。素直に参照整合性制約を一時削除し、データの削除完了後に再度作成する。
テーブル名や列名にスペースやマルチバイト文字が入ってて命名規則を満たしていない、明らかに数量データなのに文字列型になっている...といった問題はこれ以降にじっくりリファクタリングしていく。上記の手順とリファクタリングを同時に行うのはリスクが大きい。