雑文発散

«前の日記(2015-08-16) 最新 次の日記(2015-08-18)» 編集
過去の日記

2015-08-17 [長年日記]

[Emacs] sql-mode で Emacs の中からクエリを実行する

せっかく手元に PostgreSQL 環境を作ったし、Emacs も新しくしたし、そろそろまともに sql-mode を使ってみようかなと思って試してみたのでちょっとまとめた。

このあたりの記事を参考にした。

とは言え、自分の設定は上の記事に書かれているものよりだいぶシンプル。あとで必要なら足せばいいかなくらいの感じ。

(eval-after-load "sql"
  '(load-library "sql-indent"))

(defun sql-mode-hooks()
  (setq sql-indent-offset 2)
  (setq indent-tabs-mode nil)
  (sql-set-product "postgres"))

(add-hook 'sql-mode-hook 'sql-mode-hooks)

これだけだと SQL 構文のハイライトとかにしかならないので、インタラクティブにクエリを実行するための設定をしてやる。本当は設定ファイルに書いたりするわけだけど、今回は手動で接続情報を入力する。

M-x sql-set-sqli-buffer

これを実行すると、ミニバッファで PostgreSQL の接続ユーザーやデータベース名、サーバ名が聞かれてくるのでそれぞれ答えると、次のような画面が開かれる。

sql-mode

*SQL* というバッファを見て分かるとおり、これは psql コマンドのプロントそのもの。このバッファに直接入力することで、クエリの実行ができる。

sql-mode

ちなみに赤いカーソルのように見えているのは「行末のホワイトスペース」。グローバル設定で「行末のホワイトスペースは赤く表示する」というのを入れているので、それがこのバッファにも適用されてしまっている。

そして今回の本題。SQL を書いているバッファで C-c C-b (sql-send-buffer) を入力すると、*SQL* バッファにクエリが送信され、実行される。

sql-mode

これで「SQL をちょっと修正して、すぐに実行して試す」という流れが Emacs から離れずにスムーズに行える。気持ちいい。

ちょっとした注意点としては、(この sql-mode に限らないけど)大量の結果が返ってくるクエリには LIMIT 句を付けたほうが良い。付け忘れると、延々と *SQL* バッファに結果が追記されていってなかなか戻ってこない。そんな時、PostgreSQL の場合は *SQL* バッファへ移動して、C-c でインタラプトすることができる。これはおそらく sql-mode の機能ではなく、psql コマンドがもともと持っている機能だと思う。

先ほどの C-c C-b はバッファ内の全てのクエリを実行するコマンドなのだけど、バッファ内の一部のクエリだけを実行したい場合などは、別のコマンドで実現できる。クエリ実行まわりのコマンドには次のものがある。実行したい内容に応じて使い分ければ良さそうだ。

キーバインド コマンド 内容
C-c C-b sql-send-buffer バッファ内の全てのクエリを送信・実行
C-c C-c sql-send-paragraph カーソル位置のクエリを送信・実行
C-c C-r sql-send-region リージョン(範囲)内のクエリを送信・実行
C-c C-s sql-send-string ミニバッファでクエリ入力し実行
C-c C-z sql-show-sqli-buffer インタラクティブバッファを表示

今回は PostgreSQL の例だけど、MySQL や SQLite でも同じように使える。(sql-set-product "postgres") の部分を mysql とか sqlite にしてやればいい。これは M-x sql-set-product でも設定できる。

オレとしては、最近多用している Hive でこれが使えると嬉しいのだけど、sql-mode 本体には Hive 用の処理が組み込まれていない。

ちょっと調べたところだと、hive-el を組み込めば、Hive が使えそうな雰囲気がある。でも、いま使っている Hive は接続方法がちょっと特殊なので、組み込んでも使えそうにないんだよなぁ。