【bat】バッチファイルでデータベースにSQLを実行する方法完全ガイド|MySQL・PostgreSQL・SQLServer・Oracle・エラーハンドリング・実践パターンまで

バッチファイルからデータベースにSQLを実行する場面は多くあります。定期バックアップ・データ移行・ヘルスチェック・バッチ更新など、手作業を自動化することで作業ミスをなくし運用コストを大幅に削減できます。

この記事では MySQL・PostgreSQL・SQL Server・Oracle の4大DBMSをカバーし、基本コマンドからパスワードの安全な管理・エラーハンドリング・実務パターンまで体系的に解説します。

この記事でわかること

  • MySQL(mysql コマンド)でSQLファイル・直接クエリを実行する方法
  • PostgreSQL(psql コマンド)でSQLを実行する方法
  • SQL Server(sqlcmd)でSQLを実行する方法
  • Oracle(sqlplus)でSQLを実行する方法
  • パスワードをバッチに直書きしない安全な管理方法
  • エラーハンドリング・ログ出力・定期実行
  • 落とし穴5選・実践例3本・FAQ6問
スポンサーリンク
  1. 1. MySQL でのSQL実行(mysql コマンド)
    1. 1-1. SQLファイルを実行する
    2. 1-2. 直接クエリを実行する(-e オプション)
    3. 1-3. 結果をファイルに出力する
  2. 2. mysql コマンドオプション完全解説
  3. 3. PostgreSQL でのSQL実行(psql コマンド)
    1. 3-1. SQLファイルを実行する
    2. 3-2. 直接クエリを実行する(-c オプション)
    3. 3-3. psql 主要オプション
  4. 4. SQL Server でのSQL実行(sqlcmd)
    1. 4-1. SQLファイルを実行する
    2. 4-2. 直接クエリを実行する(-Q オプション)
    3. 4-3. sqlcmd 主要オプション
  5. 5. Oracle でのSQL実行(sqlplus)
    1. 5-1. SQLファイルを実行する
    2. 5-2. 直接クエリを実行する(ヒアドキュメント方式)
  6. 6. パスワードの安全な管理
    1. 6-1. MySQL:オプションファイル(.cnf/.ini)を使う
    2. 6-2. 環境変数から読み込む
    3. 6-3. パスファイルを使う(PostgreSQL .pgpass)
  7. 7. エラーハンドリングとログ出力
  8. 8. DBMS別コマンド早見表
  9. 9. 落とし穴5選と対策
    1. 落とし穴1:パスワードをバッチに直書きするとセキュリティリスク
    2. 落とし穴2:sqlplus はデフォルトでSQLエラーを無視する
    3. 落とし穴3:psql はエラーがあっても ERRORLEVEL 0 を返す(デフォルト)
    4. 落とし穴4:mysql コマンドの -p とパスワードの間にスペースを入れると失敗する
    5. 落とし穴5:SQLファイルのパスにスペースが含まれると失敗する
  10. 10. 実践例3本
    1. 実践例1:毎日の定期バックアップSQL(MySQL)
    2. 実践例2:データ移行スクリプト(PostgreSQL)—トランザクション制御付き
    3. 実践例3:DB接続ヘルスチェック(複数DB同時確認)
  11. FAQ

1. MySQL でのSQL実行(mysql コマンド)

MySQL の CLI ツール mysql を使ってバッチファイルから SQL を実行します。

1-1. SQLファイルを実行する

@echo off
setlocal

set "MYSQL=mysql"
set "HOST=localhost"
set "PORT=3306"
set "USER=root"
set "PASS=your_password"
set "DB=mydb"
set "SQL_FILE=C:\work\sql\update.sql"

:: < でSQLファイルを標準入力として渡す
%MYSQL% -h %HOST% -P %PORT% -u %USER% -p%PASS% %DB% < "%SQL_FILE%"
set "ERR=%ERRORLEVEL%"

if %ERR% neq 0 (
    echo [ERROR] MySQL SQL実行失敗 (exit code: %ERR%)
    exit /b %ERR%
)
echo [OK] SQL実行完了
endlocal

1-2. 直接クエリを実行する(-e オプション)

@echo off
setlocal

set "MYSQL=mysql"
set "HOST=localhost"
set "USER=root"
set "PASS=your_password"
set "DB=mydb"

:: -e: SQL文を直接指定して実行
%MYSQL% -h %HOST% -u %USER% -p%PASS% %DB% -e "SELECT COUNT(*) FROM users WHERE active=1;"

:: 複数のSQL文を ; で区切って一度に実行
%MYSQL% -h %HOST% -u %USER% -p%PASS% %DB% -e "UPDATE orders SET status='closed' WHERE date < NOW() - INTERVAL 30 DAY; COMMIT;"

endlocal

1-3. 結果をファイルに出力する

@echo off
setlocal

set "MYSQL=mysql"
set "USER=root"
set "PASS=your_password"
set "DB=mydb"
set "OUTFILE=C:\work\result.txt"

:: クエリ結果をファイルにリダイレクト
%MYSQL% -h localhost -u %USER% -p%PASS% %DB% -e "SELECT id, name FROM users;" > "%OUTFILE%" 2>&1

:: CSV形式で出力(タブ区切りをカンマに変換)
:: -N: ヘッダ非表示 / --batch: タブ区切り出力
%MYSQL% -h localhost -u %USER% -p%PASS% -N --batch %DB% -e "SELECT id,name,email FROM users;" > "%OUTFILE%"

endlocal

2. mysql コマンドオプション完全解説

オプション 意味 用途
-h ホスト 接続先ホスト名またはIP リモートDB接続
-P ポート 接続ポート(デフォルト3306) 非標準ポート指定
-u ユーザー 接続ユーザー名 必須
-p[パスワード] パスワード(-p の直後・スペースなし) バッチ処理では -p%PASS% の形式
--defaults-file=ファイル 認証情報ファイルを指定 パスワードをバッチに書かない安全な方法
-e "SQL" SQL文を直接指定して実行 1〜数行のクエリ実行
-N カラムヘッダを非表示 スクリプト処理・CSV出力
--batch タブ区切り出力(TSV形式) 後処理しやすい出力
-s サイレントモード(警告を抑制) ログをクリーンに保つ
--connect-timeout=N 接続タイムアウト(秒) ネットワーク不安定時
-v 詳細出力(実行したSQL文も表示) デバッグ・監査ログ

3. PostgreSQL でのSQL実行(psql コマンド)

3-1. SQLファイルを実行する

@echo off
setlocal

set "PSQL=psql"
set "HOST=localhost"
set "PORT=5432"
set "USER=postgres"
set "DB=mydb"
set "SQL_FILE=C:\work\sql\update.sql"

:: PGPASSWORD 環境変数でパスワードを渡す(psql は -p オプション非対応)
set "PGPASSWORD=your_password"

:: -f: SQLファイルを指定
%PSQL% -h %HOST% -p %PORT% -U %USER% -d %DB% -f "%SQL_FILE%"
set "ERR=%ERRORLEVEL%"

if %ERR% neq 0 (
    echo [ERROR] PostgreSQL SQL実行失敗 (exit code: %ERR%)
    exit /b %ERR%
)
echo [OK] SQL実行完了
endlocal

3-2. 直接クエリを実行する(-c オプション)

@echo off
setlocal

set "PGPASSWORD=your_password"

:: -c: SQL文を直接指定
psql -h localhost -U postgres -d mydb -c "SELECT COUNT(*) FROM users;"

:: -t: ヘッダ・フッタなしで値のみ出力(スクリプト処理向け)
psql -h localhost -U postgres -d mydb -t -c "SELECT COUNT(*) FROM users;"

:: --csv: CSV形式で出力
psql -h localhost -U postgres -d mydb --csv -c "SELECT id,name FROM users;" > "C:\work\users.csv"

endlocal

3-3. psql 主要オプション

オプション 意味 用途
-h ホスト 接続先ホスト リモートDB接続
-p ポート 接続ポート(デフォルト5432) 非標準ポート
-U ユーザー 接続ユーザー(大文字U) 必須
-d データベース 接続データベース 必須
-f ファイル SQLファイルを実行 スクリプト実行
-c SQL SQL文を直接実行 1行クエリ
-t ヘッダ・罫線なし出力 値のみ取得
--csv CSV形式出力 データエクスポート
-v 変数=値 SQL内変数を設定 動的SQL実行
-q サイレントモード 余分な出力を抑制
--set ON_ERROR_STOP=1 エラー時に即停止 SQLファイル実行時必須
psql のエラーハンドリング:ON_ERROR_STOP が重要
デフォルトでは psql はSQLエラーが発生しても処理を続行します。--set ON_ERROR_STOP=1 を付けることで、エラー発生時に即座に終了し ERRORLEVEL に 3 を返します。
@echo off
setlocal
set "PGPASSWORD=your_password"

:: ON_ERROR_STOP=1: SQLエラーで即停止(exit code 3 が返る)
psql -h localhost -U postgres -d mydb --set ON_ERROR_STOP=1 -f "C:\work\migrate.sql"
set "ERR=%ERRORLEVEL%"

if %ERR% neq 0 (
    echo [ERROR] マイグレーション失敗 (exit code: %ERR%)
    exit /b %ERR%
)
echo [OK] マイグレーション完了
endlocal

4. SQL Server でのSQL実行(sqlcmd)

sqlcmd は SQL Server 標準の CLI ツールです。Windows 認証・SQL Server 認証の両方に対応しています。

4-1. SQLファイルを実行する

@echo off
setlocal

set "SQLCMD=sqlcmd"
set "SERVER=localhost"
set "DB=MyDatabase"
set "SQL_FILE=C:\work\sql\update.sql"

:: Windows認証(-E)でSQLファイルを実行
:: -b: SQLエラー時に異常終了してERRORLEVELを設定(重要)
%SQLCMD% -S %SERVER% -d %DB% -E -b -i "%SQL_FILE%"
set "ERR=%ERRORLEVEL%"

:: SQL Server 認証を使う場合
:: %SQLCMD% -S %SERVER% -d %DB% -U sa -P your_password -b -i "%SQL_FILE%"

if %ERR% neq 0 (
    echo [ERROR] sqlcmd 実行失敗 (exit code: %ERR%)
    exit /b %ERR%
)
echo [OK] SQL実行完了
endlocal

4-2. 直接クエリを実行する(-Q オプション)

@echo off
setlocal

:: -Q: SQLを実行して終了 / -b: エラー時に異常終了(ERRORLEVELを設定)
sqlcmd -S localhost -d MyDatabase -E -b -Q "SELECT COUNT(*) FROM dbo.Users WHERE Active=1"

:: 結果をファイルに出力
sqlcmd -S localhost -d MyDatabase -E -b -Q "SELECT * FROM dbo.Orders" -o "C:\work\orders.txt"

:: ヘッダなし・区切り文字指定でCSV風出力
sqlcmd -S localhost -d MyDatabase -E -b -h-1 -s"," -W -Q "SELECT id,name FROM dbo.Users" -o "users.csv"

endlocal

4-3. sqlcmd 主要オプション

オプション 意味 用途
-S サーバー 接続先サーバー(インスタンス名も可) 例: -S server\SQLEXPRESS
-d データベース 接続データベース 必須
-E Windows認証(統合認証) ドメイン環境での推奨認証
-U ユーザー SQL Server 認証ユーザー -P と組み合わせ
-P パスワード パスワード -U と組み合わせ
-i ファイル SQLファイルを実行 スクリプト実行
-Q SQL SQL実行して終了 1回限りのクエリ実行
-o ファイル 出力をファイルに保存 結果の記録
-h-1 ヘッダを非表示 CSV等の後処理向け
-s 区切り文字 列区切り文字を指定 CSV出力: -s”,”
-W 末尾の空白を除去 出力の整形
-b エラー時に異常終了(ERRORLEVEL 設定) エラーハンドリングで重要
-t N クエリタイムアウト(秒) 長時間クエリの上限設定

5. Oracle でのSQL実行(sqlplus)

sqlplus は Oracle の標準 CLI ツールです。接続文字列の書式が他のDBMSと異なります。

5-1. SQLファイルを実行する

@echo off
setlocal

set "USER=scott"
set "PASS=tiger"
set "TNSNAME=ORCL"
set "SQL_FILE=C:\work\sql\update.sql"

:: sqlplus ユーザー/パスワード@接続名 @SQLファイル
sqlplus -S %USER%/%PASS%@%TNSNAME% @"%SQL_FILE%"
set "ERR=%ERRORLEVEL%"

:: sqlplus は SQL エラーを ERRORLEVEL に反映しない場合があるため
:: SQLファイルの末尾に WHENEVER SQLERROR EXIT 1 を記載する

if %ERR% neq 0 (
    echo [ERROR] sqlplus 実行失敗 (exit code: %ERR%)
    exit /b %ERR%
)
echo [OK] SQL実行完了
endlocal
sqlplus のエラーハンドリング:WHENEVER SQLERROR が必須
sqlplus はデフォルトでSQLエラーが発生しても処理を続け、ERRORLEVEL も更新されません。SQLファイルの先頭に以下を記載することで、SQLエラー発生時に終了コード1で終了できます。
-- SQLファイルの先頭に必ず記載する
WHENEVER SQLERROR EXIT 1
WHENEVER OSERROR  EXIT 1

-- ここから実際のSQL
UPDATE employees SET salary = salary * 1.05 WHERE dept_id = 10;
COMMIT;

EXIT 0

5-2. 直接クエリを実行する(ヒアドキュメント方式)

@echo off
setlocal

set "USER=scott"
set "PASS=tiger"
set "TNSNAME=ORCL"

:: echo でSQLを渡す(単純なクエリ向け)
echo SELECT COUNT(*) FROM employees; | sqlplus -S %USER%/%PASS%@%TNSNAME%

:: 複数行は一時ファイルに書き出してから実行
set "TMPFILE=%TEMP%\tmp_query_%RANDOM%.sql"
(
    echo WHENEVER SQLERROR EXIT 1
    echo SELECT dept_id, COUNT(*) FROM employees GROUP BY dept_id;
    echo EXIT 0
) > "%TMPFILE%"

sqlplus -S %USER%/%PASS%@%TNSNAME% @"%TMPFILE%"
set "ERR=%ERRORLEVEL%"
del "%TMPFILE%"

if %ERR% neq 0 exit /b %ERR%
echo [OK] 完了
endlocal

6. パスワードの安全な管理

バッチファイルにパスワードをハードコードするのはセキュリティリスクです。以下の方法で安全に管理してください。

6-1. MySQL:オプションファイル(.cnf/.ini)を使う

:: C:\ProgramData\MySQL\option.cnf の内容例:
:: [client]
:: user=myuser
:: password=my_secret_password
:: host=localhost

@echo off
setlocal

:: --defaults-file でオプションファイルを指定(パスワードをバッチに書かない)
mysql --defaults-file="C:\ProgramData\MySQL\option.cnf" mydb < "C:\work\update.sql"
set "ERR=%ERRORLEVEL%"

if %ERR% neq 0 exit /b %ERR%
echo [OK] 完了
endlocal

6-2. 環境変数から読み込む

@echo off
setlocal

:: システム環境変数やユーザー環境変数からパスワードを読み込む
:: (事前に setx DB_PASS "your_password" でシステムに登録しておく)
if "%DB_PASS%"=="" (
    echo [ERROR] 環境変数 DB_PASS が設定されていません
    exit /b 1
)

mysql -h localhost -u myuser -p%DB_PASS% mydb < "C:\work\update.sql"

:: PostgreSQL の場合
if "%PGPASSWORD%"=="" (
    echo [ERROR] 環境変数 PGPASSWORD が設定されていません
    exit /b 1
)
psql -h localhost -U postgres -d mydb -f "C:\work\update.sql"

endlocal

6-3. パスファイルを使う(PostgreSQL .pgpass)

:: %APPDATA%\postgresql\pgpass.conf の内容例:
:: ホスト:ポート:データベース:ユーザー:パスワード
:: localhost:5432:mydb:myuser:my_secret_password
:: *:5432:*:myuser:my_secret_password  (ワイルドカード可)

@echo off
:: pgpass.conf が存在すれば PGPASSWORD 不要でパスワードを自動読み込み
psql -h localhost -U myuser -d mydb -f "C:\work\update.sql"

7. エラーハンドリングとログ出力

本番環境での自動実行では、エラーの検知・ログ記録・通知が不可欠です。

@echo off
setlocal enabledelayedexpansion

:: ===== 設定 =====
set "MYSQL=mysql"
set "HOST=localhost"
set "USER=root"
set "PASS=%DB_PASS%"
set "DB=mydb"
set "SQL_FILE=C:\work\sql\daily_update.sql"

:: ===== ログ設定 =====
set "LOGDIR=C:\work\logs"
if not exist "%LOGDIR%" mkdir "%LOGDIR%"
for /f "tokens=2 delims==." %%D in ('wmic os get LocalDateTime /value ^| findstr LocalDateTime') do set "DT=%%D"
set "LOGFILE=%LOGDIR%\sql_exec_%DT:~0,8%.log"

call :log "===== SQL実行開始: %date% %time% ====="
call :log "  DB: %DB% / SQL: %SQL_FILE%"

:: ===== SQL実行 =====
%MYSQL% -h %HOST% -u %USER% -p%PASS% %DB% < "%SQL_FILE%" >> "%LOGFILE%" 2>&1
set "ERR=%ERRORLEVEL%"

if %ERR% neq 0 (
    call :log "[ERROR] SQL実行失敗 (exit code: %ERR%)"
    echo [ERROR] 詳細は %LOGFILE% を確認してください
    exit /b %ERR%
)

call :log "[OK] SQL実行完了"
call :log "===== 終了: %date% %time% ====="
goto :eof

:log
echo %~1
echo [%date% %time%] %~1 >> "%LOGFILE%"
goto :eof

ログ管理の詳細は バッチファイルでログローテーションを実装する方法 を参照してください。

日付付きファイル名の生成は 日付と時間をファイル名に挿入する方法完全ガイド を参照してください。

8. DBMS別コマンド早見表

DBMS CLIツール SQLファイル実行 直接クエリ パスワード渡し方
MySQL mysql mysql DB < file.sql -e "SQL" -p%PASS% または –defaults-file
PostgreSQL psql psql -f file.sql -c "SQL" 環境変数 PGPASSWORD または .pgpass
SQL Server sqlcmd sqlcmd -i file.sql -Q "SQL" -P パスワード または -E(Windows認証)
Oracle sqlplus sqlplus user/pass @file.sql パイプ or 一時ファイル 接続文字列 user/pass@TNS

9. 落とし穴5選と対策

落とし穴1:パスワードをバッチに直書きするとセキュリティリスク

:: NG: パスワードをバッチに直書き(ソースコード管理・ログに残る)
mysql -u root -pmy_secret_password mydb < update.sql

:: OK: 環境変数から読み込む
mysql -u root -p%DB_PASS% mydb < update.sql

:: より安全: --defaults-file(MySQL)または .pgpass(PostgreSQL)を使う
mysql --defaults-file="C:\secure\mysql_creds.cnf" mydb < update.sql

落とし穴2:sqlplus はデフォルトでSQLエラーを無視する

:: NG: WHENEVER SQLERROR なしでは途中でエラーが出ても続行される
-- update.sql の内容:
UPDATE wrong_table SET x=1;  -- テーブルが存在しなくてもエラーにならない
INSERT INTO target ...

:: OK: SQLファイルの先頭に必ず記載
WHENEVER SQLERROR EXIT 1
WHENEVER OSERROR  EXIT 1

落とし穴3:psql はエラーがあっても ERRORLEVEL 0 を返す(デフォルト)

:: NG: ON_ERROR_STOP なしでは psql はエラーがあっても exit code 0 を返す
psql -h localhost -U postgres -d mydb -f migrate.sql
if %ERRORLEVEL% equ 0 echo 成功  :: エラーがあっても「成功」と表示される

:: OK: --set ON_ERROR_STOP=1 でエラー時に exit code 3 を返す
psql -h localhost -U postgres -d mydb --set ON_ERROR_STOP=1 -f migrate.sql
if %ERRORLEVEL% neq 0 echo [ERROR] マイグレーション失敗

落とし穴4:mysql コマンドの -p とパスワードの間にスペースを入れると失敗する

:: NG: -p とパスワードの間にスペースがあるとパスワードプロンプトが出る
mysql -u root -p mypassword mydb < update.sql
:: → パスワード入力待ちになってバッチが止まる

:: OK: -p の直後にパスワードを付ける(スペースなし)
mysql -u root -pmypassword mydb < update.sql
mysql -u root -p%PASS% mydb < update.sql

落とし穴5:SQLファイルのパスにスペースが含まれると失敗する

:: NG: パスにスペースが含まれる場合は引用符なしでは失敗
mysql -u root -ppass mydb < C:\My Work\update.sql

:: OK: パスを二重引用符で囲む
mysql -u root -p%PASS% mydb < "C:\My Work\update.sql"

:: sqlcmd でも同様
sqlcmd -S localhost -d MyDB -E -i "C:\My Work\update.sql"

エラーハンドリングの詳細は ERRORLEVELを使ったエラーハンドリング完全ガイド、条件分岐は バッチファイルで条件分岐する方法完全ガイド を参照してください。

10. 実践例3本

実践例1:毎日の定期バックアップSQL(MySQL)

毎日深夜にテーブルのバックアップSQL(INSERT SELECT)を実行してログを残すパターンです。

@echo off
setlocal enabledelayedexpansion

:: ===== 設定 =====
set "MYSQL=mysql"
set "HOST=localhost"
set "USER=root"
set "DB=production"
set "LOGDIR=C:\work\db_logs"

if "%DB_PASS%"=="" (
    echo [ERROR] 環境変数 DB_PASS が未設定
    exit /b 1
)

if not exist "%LOGDIR%" mkdir "%LOGDIR%"

:: 今日の日付を取得
for /f "tokens=2 delims==." %%D in ('wmic os get LocalDateTime /value ^| findstr LocalDateTime') do set "DT=%%D"
set "TODAY=%DT:~0,8%"
set "LOGFILE=%LOGDIR%\backup_%TODAY%.log"

echo [%date% %time%] バックアップSQL開始 >> "%LOGFILE%"

:: 一時SQLファイルを生成
set "TMPFILE=%TEMP%\daily_backup_%RANDOM%.sql"
(
    echo SET autocommit=0;
    echo INSERT INTO orders_backup_%TODAY% SELECT * FROM orders WHERE DATE(created_at) = CURDATE() - INTERVAL 1 DAY;
    echo COMMIT;
) > "%TMPFILE%"

%MYSQL% -h %HOST% -u %USER% -p%DB_PASS% %DB% < "%TMPFILE%" >> "%LOGFILE%" 2>&1
set "ERR=%ERRORLEVEL%"
del "%TMPFILE%"

if %ERR% neq 0 (
    echo [%date% %time%] [ERROR] バックアップ失敗 (RC=%ERR%) >> "%LOGFILE%"
    exit /b %ERR%
)

echo [%date% %time%] [OK] バックアップSQL完了 >> "%LOGFILE%"
endlocal

実践例2:データ移行スクリプト(PostgreSQL)—トランザクション制御付き

マイグレーションSQLをトランザクション内で実行し、エラー時に自動ロールバックするパターンです。

@echo off
setlocal

set "PGPASSWORD=%PG_PASS%"
set "PSQL=psql"
set "HOST=localhost"
set "USER=postgres"
set "DB=myapp"
set "SQL_FILE=C:\work\migrate_v2.sql"
set "LOGFILE=C:\work\migrate.log"

if not exist "%SQL_FILE%" (
    echo [ERROR] SQLファイルが見つかりません: %SQL_FILE%
    exit /b 1
)

echo [%date% %time%] マイグレーション開始 >> "%LOGFILE%"

:: ON_ERROR_STOP=1: SQLエラーで即停止 → トランザクションが自動ロールバック
%PSQL% -h %HOST% -U %USER% -d %DB% --set ON_ERROR_STOP=1 -f "%SQL_FILE%" >> "%LOGFILE%" 2>&1
set "ERR=%ERRORLEVEL%"

if %ERR% neq 0 (
    echo [%date% %time%] [ERROR] マイグレーション失敗 (RC=%ERR%) ロールバック実施 >> "%LOGFILE%"
    echo [ERROR] 詳細: %LOGFILE%
    exit /b %ERR%
)

echo [%date% %time%] [OK] マイグレーション完了 >> "%LOGFILE%"
endlocal

migrate_v2.sql の先頭に BEGIN;、末尾に COMMIT; を記載することで、エラー時には PostgreSQL が自動的にロールバックします。

実践例3:DB接続ヘルスチェック(複数DB同時確認)

複数のデータベースに対してSELECT 1 を実行し、接続確認とレイテンシを計測するパターンです。

@echo off
setlocal enabledelayedexpansion

set "ALL_OK=1"
set "LOGFILE=C:\work\db_health_%date:~0,4%%date:~5,2%%date:~8,2%.log"

echo [%date% %time%] ===== DB ヘルスチェック開始 ===== >> "%LOGFILE%"

:: MySQL 接続確認
mysql -h localhost -u healthcheck -p%HEALTH_PASS% -e "SELECT 1;" --connect-timeout=5 >nul 2>&1
set "RC_MY=!ERRORLEVEL!"
if !RC_MY! equ 0 (
    echo [OK]   MySQL       localhost:3306 >> "%LOGFILE%"
) else (
    echo [FAIL] MySQL       localhost:3306 (RC=!RC_MY!) >> "%LOGFILE%"
    set "ALL_OK=0"
)

:: PostgreSQL 接続確認
set "PGPASSWORD=%HEALTH_PASS%"
psql -h localhost -U healthcheck -d postgres -c "SELECT 1;" -q >nul 2>&1
set "RC_PG=!ERRORLEVEL!"
if !RC_PG! equ 0 (
    echo [OK]   PostgreSQL  localhost:5432 >> "%LOGFILE%"
) else (
    echo [FAIL] PostgreSQL  localhost:5432 (RC=!RC_PG!) >> "%LOGFILE%"
    set "ALL_OK=0"
)

:: SQL Server 接続確認
sqlcmd -S localhost -E -Q "SELECT 1" -t 5 >nul 2>&1
set "RC_SS=!ERRORLEVEL!"
if !RC_SS! equ 0 (
    echo [OK]   SQL Server  localhost:1433 >> "%LOGFILE%"
) else (
    echo [FAIL] SQL Server  localhost:1433 (RC=!RC_SS!) >> "%LOGFILE%"
    set "ALL_OK=0"
)

echo [%date% %time%] ===== チェック完了 ===== >> "%LOGFILE%"

if !ALL_OK! equ 0 (
    echo [ERROR] 接続失敗のDBがあります。%LOGFILE% を確認してください
    exit /b 1
)
echo [OK] 全DB接続確認完了
endlocal

setlocal enabledelayedexpansion の詳細は setlocal enabledelayedexpansion 完全ガイド を参照してください。

自動バックアップの設計は バッチファイルで自動バックアップを作成する方法 も参照してください。

FAQ

Q. mysql コマンドで「-p の直後にパスワードを付けるな」という警告が出ます。
A. mysql: [Warning] Using a password on the command line interface can be insecure. というメッセージです。これは警告であり処理は続行されます。バッチでこの警告を抑制するには --defaults-file を使った認証情報ファイルを利用することを推奨します。警告を無視してよい場合は 2>nul でエラー出力を破棄できますが、本物のエラーも見えなくなるため注意してください。
Q. sqlplus で接続はできるのにSQLエラーが ERRORLEVEL に反映されません。
A. sqlplus はデフォルトでSQLエラーを無視します。SQLファイルの先頭に WHENEVER SQLERROR EXIT 1 を必ず記載してください。この1行がないと UPDATE が失敗してもバッチは成功扱いになります。
Q. バッチからSQLを実行したときの出力(SELECT結果)をファイルに保存したい。
A. > "output.txt" でリダイレクトできます。標準出力と標準エラー出力を両方保存するには > "output.txt" 2>&1 を使います。MySQL では -N --batch オプションでヘッダなしのタブ区切り出力になり後処理しやすくなります。CSV形式なら PostgreSQL の --csv オプションが便利です。
Q. バッチからSQL実行後にトランザクションを確実にコミット/ロールバックさせたい。
A. SQLファイル内で明示的に COMMIT;(または ROLLBACK;)を記載してください。MySQL ではデフォルト autocommit=1 のため不要な場合もありますが、SET autocommit=0; でトランザクション管理することを推奨します。PostgreSQL では BEGIN;COMMIT; で囲みます。
Q. SQLのパラメータを動的に変えてバッチから実行したい。
A. バッチ変数でSQL文を組み立てて一時ファイルに書き出し、それをCLIに渡す方法が一般的です。例えば「今日の日付」を含むSQLなら、バッチで %date% を使ってSQL文字列を動的に生成し一時ファイルに保存→実行→削除というフローになります。SQL Server の sqlcmd では -v 変数名=値 で SQLファイル内の $(変数名) を置換できます。
Q. MySQL に接続できず「ERROR 2003: Can’t connect to MySQL server」が出ます。
A. 主な原因は①MySQLサービスが起動していない、②ホスト名・ポートが間違っている、③ファイアウォールがポートをブロックしている、④ユーザーに接続元ホストからのアクセス権限がない、の4つです。mysql -h localhost -u root -p -e "SELECT 1;" で手動接続を確認してから、バッチに組み込んでください。