MySQLコマンドラインで直接クエリを実行する方法【-eオプション完全解説】

2014年6月3日


「ちょっとSQLを1つ確認したいだけなのに、mysqlコンソールにログインして実行して、quitで抜けて……」という手間を感じたことはないでしょうか。

MySQLには -e オプションを使うことで、コンソールに入ることなくコマンドラインから直接SQLを実行できる機能があります。使いこなすと、データ確認・バッチ処理・シェルスクリプト連携など、開発・運用の効率が大きく向上します。

この記事では、mysql -e の基本的な使い方から、ファイル出力・複数クエリの実行・シェルスクリプトへの組み込みまで、実際のコマンド例とともに詳しく解説します。

MySQLコマンドラインでクエリを直接実行するターミナルの様子


この記事で解決できること

  • mysql -e オプションでコンソールに入らずにSQLを実行する方法
  • ✅ 実行結果をTSV・CSVファイルに書き出す方法
  • ✅ 複数クエリをまとめて実行する方法
  • ✅ シェルスクリプトやcronから呼び出す実用的なパターン
  • ✅ よくあるエラーと対処法

動作確認環境: Linux/macOS / MySQL 5.7・8.0・8.4 / bash


基本: -e オプションでSQLをそのまま実行する

mysql コマンドに -e オプション(--execute)を渡すと、コンソールプロンプト(mysql>)を開かずにSQLを実行できます。

mysql -u ユーザー名 -p -D データベース名 -e "SQLクエリ"

実際の例

# usersテーブルの全件を取得
mysql -uroot -p -Dmyapp_db -e "SELECT * FROM users;"

# 件数だけ確認したい場合
mysql -uroot -p -Dmyapp_db -e "SELECT COUNT(*) FROM users;"

# WHERE条件付き
mysql -uroot -p -Dmyapp_db -e "SELECT id, name, email FROM users WHERE created_at >= '2024-01-01' LIMIT 10;"

実行すると、ターミナル上にテーブル形式で結果が出力されます:

+----+----------+---------------------+
| id | name     | email               |
+----+----------+---------------------+
|  1 | 田中太郎 | tanaka@example.com  |
|  2 | 鈴木花子 | suzuki@example.com  |
+----+----------+---------------------+

オプションの説明

オプション 意味
-u または --user MySQLのユーザー名
-p または --password パスワード(後に続けて入力するか、対話的に入力)
-D または --database 接続するデータベース名
-e または --execute 実行するSQLクエリ(文字列)
-h または --host 接続先ホスト(省略時はlocalhost)
-P または --port ポート番号(省略時は3306)

注意: -p の直後にパスワードを続けて書くこともできます(例: -pMyPassword)。ただし、この方法はプロセス一覧にパスワードが表示されるため、本番環境では .my.cnf を使った認証を推奨します。


ファイルに結果を書き出す

TSV(タブ区切り)で書き出す

> でリダイレクトすれば、結果をファイルに保存できます。デフォルトでTSV形式になります:

mysql -uroot -p -Dmyapp_db -e "SELECT * FROM users;" > users.tsv

ヘッダー行(カラム名)も含まれた状態で出力されます:

id  name    email   created_at
1   田中太郎    tanaka@example.com  2024-01-15 10:00:00
2   鈴木花子    suzuki@example.com  2024-02-03 14:30:00

CSV形式で書き出す

mysql 自体にCSV出力オプションはありませんが、tr コマンドでタブをカンマに変換できます:

mysql -uroot -p -Dmyapp_db -e "SELECT * FROM users;" | tr '\t' ',' > users.csv

または、MySQLの INTO OUTFILE 構文を使う方法もあります(サーバー上のパスに書き出されます):

SELECT * FROM users
INTO OUTFILE '/tmp/users.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

ヘッダーなしで出力する(-N オプション)

スクリプトで処理する場合など、カラム名ヘッダーが不要なときは -N--skip-column-names)を使います:

mysql -uroot -p -N -Dmyapp_db -e "SELECT id, name FROM users;" > ids.txt

出力:

1   田中太郎
2   鈴木花子

MySQLの結果をファイルに書き出したTSVファイルのイメージ


表示をすっきりさせる

-s オプション(サイレントモード)でテーブル罫線を消す

通常の出力には +----+ のような罫線が入りますが、-s--silent)を使うとタブ区切りのシンプルな形式になります:

mysql -uroot -p -s -Dmyapp_db -e "SELECT id, name FROM users;"

出力(罫線なし):

id  name
1   田中太郎
2   鈴木花子

縦表示で確認する(\G 相当)

-e でも \G を末尾に付けることで、カラムを縦に並べた見やすい形式で確認できます:

mysql -uroot -p -Dmyapp_db -e "SELECT * FROM users LIMIT 1\G"

出力:

*************************** 1. row ***************************
          id: 1
        name: 田中太郎
       email: tanaka@example.com
  created_at: 2024-01-15 10:00:00

複数クエリをまとめて実行する

セミコロンで区切ることで、1回の -e で複数のSQLを実行できます:

mysql -uroot -p -Dmyapp_db -e "
  SELECT COUNT(*) AS users_count FROM users;
  SELECT COUNT(*) AS orders_count FROM orders;
  SELECT SUM(amount) AS total_sales FROM orders WHERE status = 'paid';
"

出力:

users_count
1500
orders_count
3200
total_sales
4580000

SQLファイルを実行する

クエリが長い場合や再利用したい場合は、.sql ファイルを作成してリダイレクトで読み込む方法が便利です:

# report.sql という名前で保存しておく
mysql -uroot -p -Dmyapp_db < report.sql

または -e でファイルを読み込む形にもできます:

mysql -uroot -p -Dmyapp_db -e "$(cat report.sql)"

シェルスクリプトへの組み込み

-e オプションの最大の利点は、シェルスクリプトやcronとの連携です。

パスワードを安全に扱う(.my.cnf

シェルスクリプトでパスワードをハードコードするのは危険です。~/.my.cnf に認証情報を記述しておくと、-u-p なしで接続できます:

# ~/.my.cnf
[client]
user=myuser
password=mypassword
host=localhost
chmod 600 ~/.my.cnf

これにより、スクリプトがシンプルになります:

# .my.cnf があれば -u, -p 不要
mysql -Dmyapp_db -e "SELECT COUNT(*) FROM users;"

実用的なシェルスクリプト例

日次でユーザー数をログに記録するスクリプトの例:

#!/bin/bash
# daily_check.sh

DATE=$(date +%Y-%m-%d)
DB="myapp_db"

# ユーザー数取得
USER_COUNT=$(mysql -D"$DB" -N -e "SELECT COUNT(*) FROM users;")

# 本日の新規注文数
ORDER_COUNT=$(mysql -D"$DB" -N -e "
  SELECT COUNT(*) FROM orders
  WHERE DATE(created_at) = CURDATE();
")

# 本日の売上合計
SALES=$(mysql -D"$DB" -N -e "
  SELECT COALESCE(SUM(amount), 0) FROM orders
  WHERE DATE(created_at) = CURDATE()
  AND status = 'paid';
")

echo "[$DATE] ユーザー数: $USER_COUNT, 本日注文: $ORDER_COUNT, 本日売上: ${SALES}円"

cronで定期実行する

# 毎日0時にDBの集計を実行
0 0 * * * /usr/local/bin/daily_check.sh >> /var/log/db_check.log 2>&1

シェルスクリプトとMySQLを組み合わせた自動化の概念図


データ更新・DDL操作も可能

-eSELECT だけでなく、INSERTUPDATEDELETE、DDL(テーブル操作)なども実行できます。

# テストデータの挿入
mysql -uroot -p -Dmyapp_db -e "
  INSERT INTO users (name, email) VALUES ('テストユーザー', 'test@example.com');
"

# カラムの追加
mysql -uroot -p -Dmyapp_db -e "
  ALTER TABLE users ADD COLUMN deleted_at DATETIME DEFAULT NULL;
"

# インデックスの確認
mysql -uroot -p -Dmyapp_db -e "SHOW INDEX FROM users;"

注意: 本番環境での UPDATEDELETE-e での実行時も通常のSQL同様に注意が必要です。WHERE句の付け忘れは全件更新・削除になります。


よくあるエラーと対処法

エラー: Access denied for user

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

原因: ユーザー名・パスワードが間違っているか、接続元ホストが許可されていない。

対処法:

# ユーザーと権限を確認
mysql -uroot -p -e "SELECT user, host FROM mysql.user;"

# ローカル接続には 127.0.0.1 の指定が効くことも
mysql -uroot -p -h 127.0.0.1 -Dmyapp_db -e "SELECT 1;"

エラー: Unknown database

ERROR 1049 (42000): Unknown database 'myapp_db'

対処法:

# 存在するデータベースを確認
mysql -uroot -p -e "SHOW DATABASES;"

エラー: -e オプション使用時に日本語が文字化けする

原因: 文字コードがデフォルト設定のままになっている。

対処法:

# --default-character-set を明示する
mysql -uroot -p --default-character-set=utf8mb4 -Dmyapp_db -e "SELECT * FROM posts LIMIT 5;"

または ~/.my.cnf に追記:

[client]
default-character-set=utf8mb4

mysql: [Warning] Using a password on the command line interface can be insecure.

原因: -p の後に直接パスワードを入力しているため、セキュリティ警告が出る。

対処法: ~/.my.cnf に認証情報を記載して、パスワードを引数から除く(推奨)。または 2>/dev/null で警告を抑制する(非推奨)。


まとめ

MySQLの -e オプションを使った直接クエリ実行について解説しました。

  • 基本: mysql -u ユーザー -p -D DB名 -e "SQL" で即時実行
  • ファイル出力: > リダイレクトでTSV書き出し。-N でヘッダーなし出力
  • シェルスクリプト連携: ~/.my.cnf で認証情報を管理し、変数に結果を格納
  • cronとの組み合わせ: 定期的なデータ集計・チェックの自動化が可能

ちょっとした確認作業から本格的なバッチ処理まで、-e オプションを使いこなすことでMySQL運用の効率が大きく向上します。


関連記事

未分類

Posted by GENDOSU