せっかく手元に 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*
というバッファを見て分かるとおり、これは psql コマンドのプロントそのもの。このバッファに直接入力することで、クエリの実行ができる。
ちなみに赤いカーソルのように見えているのは「行末のホワイトスペース」。グローバル設定で「行末のホワイトスペースは赤く表示する」というのを入れているので、それがこのバッファにも適用されてしまっている。
そして今回の本題。SQL を書いているバッファで C-c C-b
(sql-send-buffer) を入力すると、*SQL*
バッファにクエリが送信され、実行される。
これで「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 は接続方法がちょっと特殊なので、組み込んでも使えそうにないんだよなぁ。