6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【A5M2cmd + WinMerge】データ抽出&比較検証を自動化しよう

Last updated at Posted at 2025-03-12

前書き

以前、「リプレース対応前後の旧システム・新システムにおいて、アウトプットテーブルの内容が完全一致するかどうか検証したい」といった機会がありました。

大量のテーブル & 大量のデータ を比較するので時間がかかる…
単純比較するだけ なのでそこまで手間をかけたくない…

という思いから、自動比較検証スクリプトを作成しました。どなたかのお役に立てれば幸いです。

この記事で紹介しているスクリプト

batファイルを実行するだけでデータの比較検証ができるスクリプトを作ります。
👇処理イメージは以下の通りです。

  1. A5M2cmdで、比較対象のデータを取得し、CSVファイルに出力する
  2. WinMergeコマンドで、出力したCSVファイルを比較する
  3. WinMerge比較結果をHTML形式のレポートに吐き出す

用意するもの

  • WinMerge
  • A5M2
  • A5M2cmd

サンプルコード全量

<👇①実行対象のbat>
@echo off

rem フォルダ名やファイル名に使用するジョブ名を設定
set JOB_NAME=TEST

rem ログファイルのパス設定
set LOG_FOLDER=log
set yyyyMMdd=%date:/=%
set hhmmss=%time::=%
set hhmmss=%hhmmss:~0,6%
set hhmmss=%hhmmss: =0%
set logfile=%yyyyMMdd%\%LOG_FOLDER%\%JOB_NAME%_%yyyyMMdd%_%hhmmss%.log

rem エクスポートフォルダ設定
set NEW_CSV_FOLDER=%yyyyMMdd%\%JOB_NAME%_NEW
set OLD_CSV_FOLDER=%yyyyMMdd%\%JOB_NAME%_OLD

rem 比較結果フォルダ設定
set RESULT_FOLDER=%yyyyMMdd%\%JOB_NAME%_RESULT

rem 各種フォルダ作成
mkdir %yyyyMMdd%
mkdir %yyyyMMdd%\%LOG_FOLDER%
mkdir %NEW_CSV_FOLDER%
mkdir %OLD_CSV_FOLDER%
mkdir %RESULT_FOLDER%

rem 新旧のデータ取得
rem (補足)比較したいテーブル名をテキストファイルに列挙しておく
for /f "tokens=* delims=" %%i in (%JOB_NAME%_比較対象テーブル.txt) do (
  @echo %%i
  call 99_output_with_select.bat %%i           | findstr "." >> "%logfile%"
)

rem CSVファイルを出力したフォルダを丸ごと比較検証(後続で比較検証バッチの実行結果(ERRORLEVEL)を取得するため、findstrコマンドは実行しない。 )
call 99_compare_new_and_old_folders.bat  >> "%logfile%"

rem 標準出力されたERRORLEVELを取得
echo %ERRORLEVEL%
set RETURN_CODE=%ERRORLEVEL%
pause

rem エクスポートフォルダをzip圧縮
powershell compress-archive -Force %NEW_CSV_FOLDER%/* %NEW_CSV_FOLDER%.zip
powershell compress-archive -Force %OLD_CSV_FOLDER%/* %OLD_CSV_FOLDER%.zip

rem エクスポートフォルダを削除
rmdir /s /q %NEW_CSV_FOLDER%
rmdir /s /q %OLD_CSV_FOLDER%

exit /b %RETURN_CODE%
<👇②データ取得 & CSVファイル出力をする「99_output_with_select.bat」>
@echo off

rem 【説明】新・現行からSELECT文でデータを取得し、CSVファイルに出力する。

rem 【前提①】[NEW_SQL]フォルダに新システムから比較検証データを取得するSQL(テーブル名.sql)を作成しておくこと。
rem 【前提②】[OLD_SQL]フォルダに現行システムから比較検証データを取得するSQL(テーブル名.sql)を作成しておくこと。

rem DB接続文字列取得(NEW_CONNECTION/OLD_CONNECTION)
call connection_string.bat

@echo on

rem ---------------------------------------------------------------------------
rem 検証対象のテーブル名取得
set TARGET_TABLE=%1

rem SQL文格納先パス設定
set NEW_SQL_PATH=NEW_SQL\%TARGET_TABLE%.sql
set OLD_SQL_PATH=OLD_SQL\%TARGET_TABLE%.sql

rem 新システムのデータ取得
A5M2cmd "/Connect=%NEW_CONNECTION%" ^
/RunSQL ^
/FileName=%NEW_SQL_PATH% ^
/FilePattern=%NEW_CSV_FOLDER%\%TARGET_TABLE%.csv

rem 現行システムのデータ取得
A5M2cmd "/Connect=%OLD_CONNECTION%" ^
/RunSQL ^
/FileName=%OLD_SQL_PATH% ^
/FilePattern=%OLD_CSV_FOLDER%\%TARGET_TABLE%.csv
rem ---------------------------------------------------------------------------

@echo off
<👇上のbatで呼び出していた「connection_string.bat」>
rem ※ご自分のDB環境に合わせて記載を修正してください。

rem 新システムの接続文字列
set NEW_CONNECTION=__ConnectionType=Internal;ProviderName=SQL Server;ServerName=[サーバ名];Database=[データベース名];Authentication=OS;SavePassword=False;MaxDatabaseSize=128;MaxBufferSize=640;PacketSize=4096

rem 現行システムの接続文字列
set OLD_CONNECTION=__ConnectionType=Internal;ProviderName=Oracle;Direct=True;ServerName=[サーバ名];Port=[ポート番号];Database=[データベース名];SavePassword=False;UserName=[ユーザー名];Password=[パスワード]
<👇③WinMergeによる比較を行う「99_compare_new_and_old_folders.bat」>
@echo off

rem 【説明】WinMergeコマンドによりフォルダごと比較する。
rem 比較結果は[yyyymmdd/ジョブ名_RESULT/ジョブ名_フォルダ比較.html]に出力する。

@echo on

rem --------------------------------------------------------------------------- 
rem WinMergeコマンドで新旧フォルダ比較
WinMergeU %NEW_CSV_FOLDER% %OLD_CSV_FOLDER% ^
  /minimize ^
  /noninteractive ^
  /wl ^
  /wr ^
  /u ^
  /ignorews ^
  /enableexitcode ^
  /cfg Settings/IgnoreSpace=2 ^
  /cfg Settings/DirViewExpandSubdirs=1 ^
  /cfg ReportFiles/ReportType=2 ^
  /cfg ReportFiles/IncludeFileCmpReport=1 ^
  /or "%RESULT_FOLDER%\%JOB_NAME%_フォルダ比較.html"

rem フォルダ比較結果を確認(0: 同一, 1: 差異あり, 2: エラー)
echo 比較結果:%ERRORLEVEL%
rem ---------------------------------------------------------------------------
@echo off

実行結果イメージ

①の、実行対象batをキックすると、以下のようなフォルダ構成でCSVファイル・HTMLレポートなどが出力されます。

[20250101](実行日)
 ┣ [JBXXX_RESULT](WinMerge比較結果)
 ┃ ┣ [JBXXX_フォルダ比較.files]
 ┃ ┗ [JBXXX_フォルダ比較.html]
 ┣ [log]
 ┃ ┗ [JBXXX_20250101_123456.log]
 ┣ [JBXXX_NEW.zip](比較対象データCSVファイルをzip圧縮したもの)
 ┗ [JBXXX_OLD.zip](同上)

解説

①実行対象batの解説

序盤はCSVファイルやWinMergeレポートファイルのファイル名や、出力先フォルダを設定・作成しているだけです。

@echo off

rem フォルダ名やファイル名に使用するジョブ名を設定
set JOB_NAME=TEST

(中略)

rem 各種フォルダ作成
mkdir %yyyyMMdd%
mkdir %yyyyMMdd%\%LOG_FOLDER%
mkdir %NEW_CSV_FOLDER%
mkdir %OLD_CSV_FOLDER%
mkdir %RESULT_FOLDER%

ここで、②の「99_output_with_select.bat」(データ取得bat)を呼び出しています。
「99_output_with_select.bat」の実行結果はログファイルへ出力するようにしています。

ちなみに、「比較対象テーブル.txt」に記載したテーブル名を「99_output_with_select.bat」に渡していますが、特にテーブル物理名である必要はありません。
(「99_output_with_select.bat」内では「引数.sql」を実行して「引数.csv」に出力する…みたいな処理をしているだけ)

rem 新旧のデータ取得
rem (補足)比較したいテーブル名をテキストファイルに列挙しておく
for /f "tokens=* delims=" %%i in (%JOB_NAME%_比較対象テーブル.txt) do (
  @echo %%i
  call 99_output_with_select.bat %%i           | findstr "." >> "%logfile%"
)

ここで③の「99_compare_new_and_old_folders.bat」(データ比較bat)を呼び出しています。
こちらも「99_compare_new_and_old_folders.bat」の実行結果はログファイルへ出力するようにしています。

ちなみに、私はこのスクリプトをJP1より実行していました。
WinMergeの比較結果(0: 同一, 1: 差異あり, 2: エラー)に応じて、JP1のジョブを「正常終了・警告終了・異常終了」に遷移させたかったので、データ比較結果を「RETURN_CODE」に設定して返却するようにしています。

rem CSVファイルを出力したフォルダを丸ごと比較検証(後続で比較検証バッチの実行結果(ERRORLEVEL)を取得するため、findstrコマンドは実行しない。 )
call 99_compare_new_and_old_folders.bat  >> "%logfile%"

rem 標準出力されたERRORLEVELを取得
echo %ERRORLEVEL%
set RETURN_CODE=%ERRORLEVEL%
pause

最後に、CSVファイルを格納したフォルダをzip圧縮 & 圧縮前のフォルダを削除しています。
データ量が膨大でCSVファイルが激重になってしまったのでこの処理を加えました。

rem エクスポートフォルダをzip圧縮
powershell compress-archive -Force %NEW_CSV_FOLDER%/* %NEW_CSV_FOLDER%.zip
powershell compress-archive -Force %OLD_CSV_FOLDER%/* %OLD_CSV_FOLDER%.zip

rem エクスポートフォルダを削除
rmdir /s /q %NEW_CSV_FOLDER%
rmdir /s /q %OLD_CSV_FOLDER%

exit /b %RETURN_CODE%

②データ取得bat(99_output_with_select.bat)の解説

記載した通りですが、「NEW_SQL」フォルダと「OLD_SQL」フォルダ内に予めSELECT文を記載したSQLファイルを作成しておく必要があります。
また、「connection_string.bat」で、A5M2cmdよりDB接続する際に必要となるDB接続情報を定義しておく必要があります。

@echo off

rem 【説明】新・現行からSELECT文でデータを取得し、CSVファイルに出力する。

rem 【前提①】[NEW_SQL]フォルダに新システムから比較検証データを取得するSQL(テーブル名.sql)を作成しておくこと。
rem 【前提②】[OLD_SQL]フォルダに現行システムから比較検証データを取得するSQL(テーブル名.sql)を作成しておくこと。

rem DB接続文字列取得(NEW_CONNECTION/OLD_CONNECTION)
call connection_string.bat

@echo on」以降の処理がログファイルへ出力されます。
①実行対象batから指定された引数(テーブル物理名)より、実行対象のSQLファイルを設定します。

@echo on

rem ---------------------------------------------------------------------------
rem 検証対象のテーブル名取得
set TARGET_TABLE=%1

rem SQL文格納先パス設定
set NEW_SQL_PATH=NEW_SQL\%TARGET_TABLE%.sql
set OLD_SQL_PATH=OLD_SQL\%TARGET_TABLE%.sql

A5M2cmdを使用し、DBからデータを取得 & CSVファイルへ出力しています。
/FileNameで実行対象のSQLファイルを指定、/FilePatternで取得結果の出力先を指定しています。(もう一方のデータ取得も同様。)

rem 新システムのデータ取得
A5M2cmd "/Connect=%NEW_CONNECTION%" ^
/RunSQL ^
/FileName=%NEW_SQL_PATH% ^
/FilePattern=%NEW_CSV_FOLDER%\%TARGET_TABLE%.csv

③データ比較bat(99_compare_new_and_old_folders.bat)の解説

②データ取得batで出力したCSVファイルが格納されているフォルダを比較します。

@echo off

rem 【説明】WinMergeコマンドによりフォルダごと比較する。
rem 比較結果は[yyyymmdd/ジョブ名_RESULT/ジョブ名_フォルダ比較.html]に出力する。

こちらも「@echo on」以降の処理がログファイルへ出力されます。
WinMergeコマンドオプションの意味合いについては、コード内に説明を追記しました。

@echo on

rem --------------------------------------------------------------------------- 
rem WinMergeコマンドで新旧フォルダ比較
WinMergeU %NEW_CSV_FOLDER% %OLD_CSV_FOLDER% ^
  /minimize ^ ⇒最小化状態でWinMergeを開始
  /noninteractive ^ ⇒比較終了後にWinMergeを閉じる
  /wl ^ ⇒読み取り専用で開く(左)
  /wr ^ ⇒読み取り専用で開く(右)
  /u ^ ⇒パスを最近使用した項目に追加しない
  /ignorews ^ ⇒空白を無視する
  /enableexitcode ^ ⇒比較結果を終了コードに設定(0: 同一, 1: 差異あり, 2: エラー)
  /cfg Settings/IgnoreSpace=2 ^ ⇒空白「すべて無視」に設定
  /cfg Settings/DirViewExpandSubdirs=1 ^ ⇒自動的にサブフォルダーを展開する
  /cfg ReportFiles/ReportType=2 ^ ⇒「シンプルなHTML形式」でレポート出力
  /cfg ReportFiles/IncludeFileCmpReport=1 ^ ⇒ファイル比較レポートを含める
  /or "%RESULT_FOLDER%\%JOB_NAME%_フォルダ比較.html" ⇒レポート出力先

rem フォルダ比較結果を確認(0: 同一, 1: 差異あり, 2: エラー)
echo 比較結果:%ERRORLEVEL%

👇参考にさせていただいたサイト

ちなみに「/cfg Settings/etc...」や「/cfg ReportFiles/etc...」などの値は、WinMergeの設定ファイルを出力して、実際の設定値を見ながら指定してみてもいいと思います。

👇WinMergeの設定を開き、「エクスポート」を押下
image.png

👇設定ファイルの中身
image.png

あとがき

この自動比較検証スクリプトを作成したおかげで、「新システムと旧システムの実行が終わったタイミングに、JP1から検証スクリプトをキックするように設定しておくだけで、あとは放置でOK」な状況を作り出すことができました。単純作業はどんどん自動化して幸せになりたいですね。

ただ、こちらのスクリプトは私が社会人3年目の時に作ったものなので、改善の余地はたくさんあると思います。ご助言などあればコメントをお願いいたします。
ここまで読んで下さりありがとうございました。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?