Access 2003からMariaDBに移行

内製の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してデータの本番移行を行う。 データ移行の逆順で実行しても参照整合性制約からデータを削除できない場合がある。素直に参照整合性制約を一時削除し、データの削除完了後に再度作成する。 テーブル名や列名にスペースやマルチバイト文字が入ってて命名規則を満たしていない、明らかに数量データなのに文字列型になっている…といった問題はこれ以降にじっくりリファクタリングしていく。上記の手順とリファクタリングを同時に行うのはリスクが大きい。

<span title='2018-08-19 00:00:00 +0900 +0900'>August 19, 2018</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

AccessにOleDbアクセス時、日付型のパラメータを使用する場合は型を明示する必要あり

はまった… Accessのときのみ発生。 Parameterを使う際、通常、設定した値の型からよきにはからって処理してくれるが、AccessでDateTime、特に時刻部分が設定されている場合ではエラーとなる。 http://yan-note.blogspot.jp/2008/08/systemdatacommondbparameteraccessdate.html

<span title='2018-02-20 00:00:00 +0900 +0900'>February 20, 2018</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

AccessでのYes/No型を外部結合してGroupByすると「カレントレコードがありません」

タイトルの通り。 Accessで、OLEDB経由でもAccessで直接クエリをたたいても「カレントレコードがありません」と表示されるエラーに遭遇し、SQLを切り分けたところ、Yes/No型のフィールドが原因と判明。 ググってみると、Yes/No型を外部結合してGroupByすると、Nullが発生した場合に処理できず、このようなエラーが出るらしい。 https://www.pcreview.co.uk/threads/no-current-record-error-in-group-by-query-with-outer-joins-solution.2126293/ 対処法は、リンク先にある通り、SELECT、GROUP BYの双方をNzでNullの場合の値を指定すること。 OLEDB接続の場合はNz関数が利用できないので、IIfとIsNullを組み合わせる。 Access嫌だ…

<span title='2018-01-21 00:00:00 +0900 +0900'>January 21, 2018</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41

テーブル定義の移行でよく使う方法

社内DBを試行錯誤しているため、DB間データ移行の前段としてテーブル定義をコピーしたいことがある。 大抵のDBでは無料でもツールが充実しており、ODBCライブラリを入れればよっぽど問題ないと思うのだが… MySQL … Workbench Oracle … SQL Developer SQL Server … SQL Server Management Studio(SSMS) Windows 10 Pro 64bitで、SSMSからOracleにアクセスしようとしたところ、どうにもエラーでうまく行かない。64bitのInstant Client + ODBCをインストールし、OSのODBC管理ツールでテスト接続は成功しているのだが… で、こういう時はAccessでODBC経由でリンクを貼る分にはまず失敗しない。この状態でテーブルをAccessにテーブル定義のみコピーし、そのAccessのテーブルをSSMSでインポートするとうまくいく。

<span title='2017-11-30 10:51:34 +0000 UTC'>November 30, 2017</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;tack41