多くの sqlite3 コマンドには readline ライブラリや editline ライブラリがリンクされていて、 コマンドライン入力時に行編集機能や履歴参照が可能となっている。上矢印キー、 または C-p で1つ前の入力を参照、下矢印キー、または C-n で1つ新しいものを 参照、C-r で古い入力方向に、C-s で逆方向にインクリメンタルサーチ、 などのキーを使いこなすとそれなりに早くSQL文を入力できる。
ところが扱うSQLの文が大きくなり、WITH や JOIN を駆使する複数に渡るものになって来ると1行単位でしか履歴をたどれない 標準インタフェースでは試行錯誤にとても手間がかかる。 複数行に渡る長いSQL文を試すときは、 テキストファイルに文を書き込んでおいてそれを sqlite3 に渡すとよい。Emacs にはこれを効率的に処理してくれる sql-mode がある。
sql-mode は GNU Emacs のバージョン24以降に標準添付されている。 まずEmacsをインストールする。代表的なシステムでの例を示す。
sudo pkg install emacs24 # FreeBSD
sudo pacman -S emacs24 # Arch Linux
sudo apt-get -y install emacs24 # FreeBSD
標準では拡張子が .sql で終わるファイルを開くと編集モードが sql-mode になる。このモードと、SQL処理プログラムを連係させると、 キーコマンド1つでカーソル位置の問い合わせができるようになる。 ただし、sql-mode は汎用的な設計で、どんな RDBMS を使ってもよいようになっているため、SQLite3 を使う場合にはそれと分かる指定を明示的に与える必要がある。そのために、 ~/.emacs ファイルを開き以下の内容を記述する。
;;;
;; sql-mode
;;;
(setq sql-sqlite-program "sqlite3" ; SQLiteのコマンド名設定
sql-sqlite-login-params ; DBファイル拡張子に .sq3 を追加
'((database :file ".*\\.\\(db\\|sq\\(lite\\)?[23]?\\)")))
(cond
((fboundp 'modify-coding-system-alist)
(modify-coding-system-alist
'process ; sqlite3 プロセスへの送信文字を utf-8 にする
"sqlite" (cons 'undecided 'utf-8))))
本書では SQLite3 のDBファイル名に *.sq3 というファイル名を指定しているため、sql-mode でもこれを SQLite 用と判定するようにパターンを設定している。
上記の設定により、Emacsを立ち上げ直すと sql-mode が使えるようになる。 たとえばSQL文を記述・保存するファイルが foo.sql だとするとこれを開くと自動的に sql-mode になる。 ただし、そのままでは数あるRDBMSのうちどれだか sql-mode には分からないので明示的に指定し、なおかつ DB ファイルをアクセスした状態の sqlite3 起動プロセスと foo.sql を結び付ける必要がある。そのためには以下のようにする。
M-x sql-set-product [Return]
sqlite [Return]
M-x sql-product-interactive [Return]
foo.sq3 [Return]
2つ目の M-x コマンド起動で隣のバッファに sqlite3 バッファが現れる。
*SQL* 対話バッファ開始直後
*SQL* と名の付いたバッファは sqlite3 プロセスと結び付いていて、 このバッファの「sqlite>」プロンプトに文を入力するとそのまま sqlite3 に処理が渡る。また、SQL 文を保存したファイルを開いているバッファ(図では上側)で、 SQL文を複数書いておいて、その中から実行したい文のところにカーソルを置いて C-c C-c をタイプすることで *SQL* プロセスに送り込むことができる。
sql-mode で使用できる主なキーコマンドを示す。
キー | 機能名 | 機能 |
---|---|---|
C-c C-b | sql-send-buffer | バッファ中の文全体を *SQL* に送る。 |
C-c C-c | sql-send-paragraph | カーソル位置が所属する段落の文をまとめて *SQL* に送る。 |
C-c C-i | sql-product-interactive | SQL対話プロセスを起動する。 |
C-c C-s | sql-send-string | ミニバッファで文を1行読み取り、それを *SQL* に送る。 |
C-c C-r | sql-send-region | 選択した領域(リジョン)を *SQL* に送る。 |
C-c C-l t | sql-list-table | ミニバッファ入力で指定したテーブルの .schema を得る。 デフォルトでカーソル位置のテーブルが提示されるので、 問い合わせ文入力時にテーブルが持っているカラム名があやふやになったら C-c C-l t をタイプすることですぐに隣のバッファに .schema の結果を得られる。 |
複雑な問い合わせ文を試行錯誤で構築する際は、 C-c C-c (sql-send-paragraph)、1行だけの短い文を送りたいときは C-c C-s (sql-send-string) が便利である。 本書の例題プログラムに登場する問い合わせ文の構築でも、sql-mode の中で副問い合わせの部分から作成し、その都度 C-c C-c で結果を確認しながら全体の問い合わせを組み立てることでスムーズに進められた。
yuuji@koeki-u.ac.jp