Access移行のデバッグと動作検証の方法|新旧の実行結果を突き合わせる
Access移行後に新旧で同じ結果が出るかを確かめる手順を解説。件数→集計値→全行の3段階照合、並び順の落とし穴、NULL・日付・丸め・文字列という4つの確認点、並行稼働中の日次定点観測までを発注側でも使える形で整理します。
結論:移行の検証は「件数→集計値→全行」の3段階で突き合わせる
Access移行の終盤で問われるのは、「新システムは本当に同じ結果を出すのか」です。構文エラーのように実行を止める不具合は作業中に表面化しやすい一方、怖いのは「動くのに値が微妙に違う」タイプの不具合で、これは突き合わせをしない限り、狙って見つけることができません。当社はMicrosoft公開サンプルNorthwindでの変換検証で、Accessの実行結果とPostgreSQLの実行結果を行の値まで突き合わせる方法を使いました(実測の記事)。この記事では、その照合の考え方を、読者が自分の移行プロジェクトで使える手順に一般化して説明します。
クエリ(帳票・画面の元になる集計)1本ごとの照合は、粗い順に3段階で進めます。
| 段階 | 突き合わせるもの | 見つかる不具合の例 |
|---|---|---|
| ① 件数 | 新旧の行数(COUNT) | 結合条件の誤りによる行の増減、抽出条件の取りこぼし |
| ② 集計値 | 金額・数量など主要な数値列の合計(部門別・月別などの切り口で) | 丸め・NULLの扱いの違い、単価×数量の計算式の差 |
| ③ 全行 | キーで並べた全行の値 | 件数も合計も合うのに特定の行だけ違う、相殺で隠れた差異 |
①が合わないうちに②③へ進むと原因を切り分けにくいので、この順で潰していきます。①と②が一致しても安心はできません。プラスとマイナスの差異が相殺して合計だけ合っている、という形があり得るからです。最後は③、つまり全行の値まで見ます。
全行比較で最初に転ぶのは「並び順」
全行比較を始めると、中身は同じなのに並び順が違うだけで大量の不一致が出る、という空振りが起こりえます。原因は仕様です。PostgreSQLの公式ドキュメントにあるとおり、ORDER BYを指定しないSELECTの行順は不定で、当てにしてはいけません。Access側も、明示的な並べ替えを設定していなければ、見えていた順序を保証されたものとして扱わないのが安全です。
なので全行比較は、必ず主キー(それがなければ一意になる列の組)でORDER BYを付けて両側から出力し、それを突き合わせます。CSVに出して表計算ソフトで比較する素朴な方法でも、キー順に揃ってさえいれば十分機能します。SQLで完結させたい場合は、差集合(PostgreSQLならEXCEPT)で「旧にあって新にない行」「新にあって旧にない行」をそれぞれ出す方法もあります。
差異が出たら、まずNULL・日付・丸め・文字列を疑う
突合のSQLを自分で書くとき、まず引っかかるのはNULLです。PostgreSQLの公式ドキュメントにあるとおり、NULLは「=」では比較できず、7 = NULL の結果は真でも偽でもなくNULLになります。列同士の突合条件にはIS NOT DISTINCT FROM(NULL同士を一致として扱う比較)を使ってください。またAccessのNzをCOALESCEに置き換えた箇所は、「NULLのまま」か「0や空文字に変換済みか」が新旧でずれていないかを重点的に見ます。
日付では、Date()を含むクエリで「誰の今日か」が新旧でずれ得ます(PostgreSQL+React移行の記事で詳しく書きました)。もうひとつ確認したいのは時刻部分で、Accessの日付/時刻型に時刻が入っていたことに気づかず日付だけで比較すると、境界の1日分がずれます。
丸めの方式も新旧で違います。VBAのRound関数は公式ドキュメントに「いわゆる銀行家丸め(bankers rounding)を返す」と注記されているとおり、0.5ちょうどのとき偶数側へ丸めます。一方PostgreSQLのround(numeric型)は0.5をゼロから遠い方へ丸めます。端数がちょうど0.5に当たり、かつ2つの方式で結果が分かれる値でだけ、新旧の結果がずれます。1件あたりの差はわずかでも、件数が積み重なれば合計の差になって表れます。目視では気づきにくい一方、経理業務では小さくても放置できない種類の差です。
文字列は、全角半角・前後の空白・大文字小文字の揺れが結合や重複判定の結果を静かに変えます。これは検証段階で戦うより、移行前にデータ側を揃えるほうが安上がりです。移行前のデータクレンジングの記事で検出クエリを紹介しています。
「たまたま一致」を一致に数えない
実行時に外から値を受け取るクエリ(パラメータや画面の検索条件を参照するもの)は、値を決めて実行し、比較することになります。ここで手を抜いて適当な値1つで比較すると、両側とも0行が返ってきて「一致」で通ってしまうことがあります。0行同士の一致は、抽出条件が正しく移っている証拠としては弱い。条件が両側で同じように壊れていても0行は一致するからです。
当社のNorthwind検証では、この種のクエリはNULL・境界値・実在するIDの3通りの値で突き合わせ、実在するIDで行が返る(非空の)一致を必ず含めるようにしました。自分でやる場合も同じで、「行が返るケースで一致した」を最低1つ確認するのが要点です。
並行稼働中は、日次の定点観測に切り替える
切り替え前の一斉検証が終わっても、並行稼働期間中はデータが毎日動きます。この期間は全行比較を毎日やる必要はなく、①件数と②主要な集計値を日次で新旧から取り、突き合わせる定点観測に切り替えるのが現実的です。差が出た日に、その日のうちに③の全行比較で範囲を絞り込めば、原因調査が「昨日までは合っていた」という強い手掛かり付きで始められます。並行稼働期間の設計と二重入力の負担軽減は並行稼働の記事で扱っています。
どこまで続けるかは、月次の締め処理など「Accessの結果が業務の正として使われる大きな節目」を新システムで最低1回無事に越えるまで、を一つの目安と考えています(受託開発での当社の経験則です)。手元のAccessの検証をどこから始めるべきか整理したい場合は、無料の解析可否チェックもあわせてご利用ください。
よくある質問
Q. すべてのクエリで全行比較まで必要ですか。
理想はすべてですが、手作業では現実的でないことも多いはずです。優先度を付けるなら、金額に直結するもの(請求・支払・在庫)と利用頻度の高い帳票から、というのが当社の考えです。優先度の低いものも①件数の突き合わせだけはやっておくと、行が大きく増減するタイプの不具合は拾えます(本文に書いたとおり、件数の一致は中身の一致まで保証しない点には注意してください)。
Q. 専用ツールがないとできませんか。
始めるだけならCSVエクスポートと表計算ソフトで足ります。キー順に並べて出力し、値を横に並べて比較する。ただし表計算ソフトはCSVの読み込み時に日付や先頭ゼロを自動変換することがあるため、列を文字列として読み込むなどの注意は必要です。クエリの本数が多い場合や繰り返し実行する場合は、突合をSQLやスクリプトにしておくと再検証のコストが下がります。
Q. 検証は開発ベンダーに任せてよいですか。
突き合わせの実行は任せられますが、「差異が出たときにどちらの値が業務として正しいか」の最終判断には業務担当者の関与が欠かせません。検証計画には、技術側と業務側の両方の役割を入れてください。
Q. 差異が出たら、常にAccess側が正なのですか。
移行の目的が現行業務の再現である以上、基準は現行Accessです。ただし突き合わせの過程で、現行Access側の計算の誤りが見つかることもあります。その場合に「バグごと忠実に再現する」か「移行を機に直す」かは技術では決められない業務判断なので、発見のたびに記録して業務側が裁定する運用をおすすめします。
解析可否の無料チェックのご案内
保守が難しくなったAccessについて、解析が可能かどうかのみを無料でご確認いただけます。顧客データの送信は不要で、発注義務もございません。
所要約2分・ファイル送信不要・発注義務はございません/ご説明はオンラインにて承ります