第5回 SQL*Plusを使いやすくする


今回はSQL*Plusの話です。SQL*Plusは、Oracleデータベースの標準ツールとして昔から使われています。しかし昔から大きなアップデートが無いこともあり、現代のツールと比べると使い勝手が良いとは言えません。たとえベテランであっても、長いSQLを書くのは苦痛ではないでしょうか。そこで今回は「SQL*Plusを使いやすくする」いくつかの方法を説明します。

SQL*Plusを取り巻く状況

筆者が初めてOracleを使ったのは1994年のOracle7 R7.1のころだったでしょうか。20年以上前の当時でさえ、Borland Turbo Cのようなすぐれた統合環境があり、Microsoft Visual BasicやPower Builder、SQL Windowsといった統合GUI開発環境がありました。

このような状況のなか、初めてSQL*Plusを使った印象は最悪でした。ヒストリー機能も無ければ、フルスクリーンエディット機能も無い。あるのはLISTやCHANGEなど独自の編集コマンドだけ。そしてPL/SQLのデバッグ機能はC言語のprintf()相当。あまりの使いづらさにしびれました。SQL*DBAにはスクリーンモードがあったとか、Windowsのコマンドライン版sqlplus.exeにはヒストリー機能があったとかは、マニアックな話なので無視します。

現代の開発者の多くは、昔とは比べものにならないくらいに進化したEclipseやMicrosoft Visual Studioなどの統合開発環境を使うことが当たり前になっています。それに対してSQL*Plusは20年以上前から、あまり変わっていません。SQL*Plusを初めて使う人は、筆者以上に驚くでしょう。

このような背景もあり、システム開発の現場で利用されてきたのが、SI Object BrowserやToad、PL/SQL Developerなどのサードパーティー製ツールです。また現在はOracle純正の統合開発環境Oracle SQL Developerもあります(※)

ところでみなさん、Oracle SQL Developerを使っていますか? 2006年のリリース当初は問題もありましたが、現在は機能も品質も格段に向上しています。SQLをバリバリ書くには欠かせないツールです。なおOracleデータベースにバンドルされているOracle SQL Developerはバージョンが古いので、OTNからダウンロードしたものを使ってください。

Oracle SQL Developerの画面

Oracle SQL Developerの画面

  • ※Oracle SQL Developerと位置づけは異なりますが、現在はOracle JDeveloperやOracle Developer Tools for Visual Studio 、Oracle Enterprise Pack for Eclipseなどの開発ツールもあります。

SQL*Plusで好きなエディターを使用する

SQL*Plusとエディターをそれぞれ起動し、エディターで書いたSQLをSQL*Plusにコピーすることは、多くの人が行なっています。それでもよいのですが、ウインドウが使えないコンソール画面のときには使えません。また、ちょっとした間違いでもコピー&ペーストが発生するので、開発・テスト環境などでスピードを優先したいときには向いていないこともあります。

SQL*Plusでエディターを設定すると、CHANGEやADDといったコマンドを使わずに、SQLバッファを編集できるようになります。SQL*Plusのプロンプトから次のように実行します。DEFINEと_EDITORの間にはスペースがあるので間違えないようにしてください。

SQL> DEFINE _EDITIOR = vi

Linux/UNIXならばviやemacs、Windowsならばメモ帳やサクラエディタなどを指定するとよいでしょう。パスが通っていないときはフルパスで指定します。

次にエディターを起動したいときはeditコマンドを実行します。するとSQLバッファの内容を含んだ状態でエディターが起動します。

SQL> edit

エディターを終了すれば、修正したSQLバッファの内容がSQL*Plusに戻されます。実際の例を見てみます。

SQL> select * from v$version; ←SQLを初回実行

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE    11.2.0.4.0    Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

SQL> l  ← listコマンドでSQLバッファを表示
  1  select * from v$version
SQL> edit ← エディターを起動しwhere句を追加して終了
Wrote file afiedt.buf

  1  select * from v$version
  2* where banner like 'Oracle%'
SQL> /  ←修正したSQLを実行

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

SQL*Plusを終了すると設定が無効になるので、毎回利用するときには次のファイルにDEFINE文を記述します。するとSQL*Plusを使用する全員で同じ設定を共有できます。

Linux / UNIXの場合: $ORACLE_HOME/sqlplus/admin/glogin.sql
Windowsの場合: %ORACLE_HOME%\sqlplus\admin\glogin.sql

ユーザーごとに指定したい場合は、同様の内容を記述したlogin.sqlファイルをカレントディレクトリや環境変数SQLPATHで指定したディレクトリに配置します。詳細は「SQL*Plusユーザーズ・ガイドおよびリファレンス」をご覧ください。

SQL*Plusのエラーロギング機能を使う

SQL*Plus 11.1から追加された機能にエラーロギングがあります。これはSQLやPL/SQLスクリプトで発生したエラーを表に保存する機能で、長いSQLスクリプトを実行するときに役立ちます。実際に操作する場面を見てみましょう。

エラーロギングを有効にして、わざと間違ったSQLを実行します。エラーはsperrorlog表に格納されます(sperrorlog表が無いときには、set errorlogging on時に自動作成)。

SQL> set errorlogging on truncate
SQL> selet * from dual;
SP2-0734: unknown command begging “selet * fr…” - rest of line ignored.

sperrorlog表を見ると、先ほどのエラー内容が保存されていることがわかります。

SQL> select message, statement from sperrorlog;
SP2-0734: unknown command begging “selet * fr…” - rest of line ignored.
selet * from dual

従来はスクリプトの実行結果をログファイルにSPOOLして、エラーがないことをエディターの検索機能やgrepで確認していました。しかし、この方法を使えば簡単にエラーだけを抽出できます。

ヒストリー機能や入力補完機能を追加する

次にヒストリー機能と入力補完機能を追加する方法を説明します。ヒストリーは過去の入力をカーソルキーでさかのぼれる機能です。入力補完機能は、単語の一部分だけを入力し、残りの文字をタブキーで補完する機能です。いずれも生産性向上につながる機能です。

必要になるのは次の2つのプログラムです。

rlwrap:readlineライブラリのラッパー
rlwrap_ext:rlwrapの入力補完機能用Oracleキーワードライブラリ

rlwrapを使ったヒストリー/入力補完機能は、Oracle Blog(http://orablogs-jp.blogspot.jp/)をはじめ、ネット上でも紹介されているのですが、最適でない部分もあり、あらためて紹介することにします。

次の順序で設定します。

  1. readline ライブラリを利用するためのラッパー rlwrap をインストールする
  2. 入力補完のライブラリをインストールする
  3. SQL*Plus のラッパースクリプトを設定する

今回説明する手順は次のLinuxディストリビューションで使用できます。

Oracle Linux 5
Oracle Linux 6
Oracle Linux 7
Red Hat Enterprise Linux 5
Red Hat Enterprise Linux 6
Red Hat Enterprise Linux 7

今回はOracle Linux 6(x86_64)を使用して説明します。Linuxディストリビューションやrlwrap、rlwrap_extのバージョンによって、多少操作は違いますが、ご自身の環境に合わせて適宜読み替えて実行してください。

rlwrapをインストールする

rlwrapをインストールします。rlwrapは、シェルプロンプトにヒストリーや入力補完などの行編集機能を提供するreadlineライブラリのラッパーです。上記Linuxディストリビューションには含まれていないので、どこからか入手する必要があります。ソースからインストールする方法もありますが、管理しやすいRPMを推奨します。

RPMは、RHELおよび互換ディストリビューション向けにFedoraプロジェクトの有志が運営しているEPELリポジトリ (https://fedoraproject.org/wiki/EPEL/ja)を使用します。Linuxのバージョンや32bit/64bitによってパスやファイル名が違うので適宜変更してください。またここに書いてあるのは2015年6月時点の情報なので、その時点で最新のバージョンを使用してください。

rlwrapをダウンロードします。プロキシがあるネットワーク環境では/etc/wgetrcにプロキシサーバを指定します。

# wget http://dl.fedoraproject.org/pub/epel/6/x86_64/rlwrap-0.42-1.el6.x86_64.rpm

次にrlwrapをインストールします。

# rpm -ivh rlwrap-0.42-1.el6.x86_64.rpm

rlwrap_extをインストールする

次に入力補完に使用するOracleキーワードのライブラリrlwrap_extをインストールします。次のサイトから利用する DB のバージョンに応じたファイルをダウンロードします。複数のDBバージョンを使用するときには、一番新しいバージョンを選択してください。

今回は12.1用のファイルをダウンロードします。

# wget http://www.linuxification.at/download/rlwrap-extensions-V12-0.01.tar.gz

rlwrapが参照するディレクトリにコピーします。

# cp rlwrap-extensions-V12-0.01.tar.gz /usr/share/rlwrap/completions

解凍する前に中身を見てみましょう。パーミッションにxが付いていないファイルはキーワードファイルで、xが付いているファイルはラッパースクリプトです。またSQL*Plusだけでなく、asmcmdやadrci、rmanコマンドのキーワードファイルが付属していることがわかります。

# cd /usr/share/rlwrap/completions
# tar ztvf rlwrap-extensions-V12-0.01.tar.gz
-rw-r--r-- hannes/users   1257 2013-01-30 19:45 adrci
-rwxr-xr-x hannes/users     71 2014-06-04 17:21 asm+
-rw-r--r-- hannes/users    907 2013-01-30 19:45 asmcmd
-rw-r--r-- hannes/users   3411 2015-01-20 07:15 README
-rw-r--r-- hannes/users   2880 2014-01-14 21:18 README.english
-rw-r--r-- hannes/users   1948 2014-01-14 21:09 rman
-rwxr-xr-x hannes/users    899 2014-06-04 14:43 sql+
-rw-r--r-- hannes/users    744 2013-01-30 19:45 sqlplus
-rw-r--r-- hannes/users   8973 2013-10-01 23:18 sqlplus.all
-rw-r--r-- hannes/users  20625 2014-01-14 19:04 sqlplus.cdb
-rw-r--r-- hannes/users  19649 2013-10-01 23:18 sqlplus.dba
-rw-r--r-- hannes/users  10779 2014-01-14 23:08 sqlplus.dbms_packages
-rw-r--r-- hannes/users   3132 2013-01-30 19:45 sqlplus.functions
-rw-r--r-- hannes/users  11610 2013-10-01 23:19 sqlplus.gvdollar
-rw-r--r-- hannes/users   7502 2013-10-01 23:19 sqlplus.init
-rw-r--r-- hannes/users  72231 2013-10-01 23:19 sqlplus._init
-rw-r--r-- hannes/users   1377 2013-10-01 23:19 sqlplus.packages
-rw-r--r-- hannes/users   1121 2013-01-30 19:45 sqlplus.rman
-rw-r--r-- hannes/users   1348 2013-01-30 19:45 sqlplus.tables
-rw-r--r-- hannes/users   9653 2013-10-01 23:19 sqlplus.user
-rw-r--r-- hannes/users    207 2013-10-01 23:19 sqlplus.utl_packages
-rw-r--r-- hannes/users  11750 2013-10-01 23:19 sqlplus.vdollar

rlwrap_extを解凍します。

# tar zxvf rlwrap-extensions-V12-0.01.tar.gz 

続いてsql+の内容を修正します。

# vi sql+

[変更前]

R_HOME=${RLWRAP_HOME:=/usr/local/share/rlwrap/completions}

[変更後]

R_HOME=${RLWRAP_HOME:=/usr/share/rlwrap/completions}

asm+とsql+はコマンドなので、パスが通っているディレクトリにコピーします。

# cp -p sql+ asm+ /usr/local/bin

ここまでで設定作業は終了です。次に実際に使ってみます。

ヒストリー機能や入力補完機能を使ってみる

rlwrapを使う一般的な方法は次の通りです。

$ rlwrap -i コマンド名

SQL*Plusの場合には次のようになります。内部的にSQL*Plusを実行しているので、ORACLE_HOMEやPATHなどの環境変数を設定する必要はあります。

$ rlwrap -i sqlplus

ただしSQL*Plusとasmcmdについては、ラッパースクリプトが用意されているので、それを使用します。SQL*Plusの場合sql+、asmcmdの場合、asm+から起動します。

SQL*Plusを起動するときには次のように入力します。引数を指定しないときには"sqlplus / as sysdba"もしくは"sqlplus / as sysasm"と同じ意味です(ORACLE_SIDが+で始まるかどうかで自動判定)。ユーザー名や接続識別子を指定するときには、sqlplusと同様の方法で引数を指定します。

$ sql+
SQL>

これでカーソルキーを使った自由な編集ができるようになります。またタブキーを押すと、合致するコマンドやデータディクショナリが自動的に補完されます。

実際に例を紹介します。

SQL> sel

まで入力してタブキーを押すと

SQL> SELECT

まで補完されます。補完された文字は大文字に変換されます。

SQL> SELECT * FROM dba_u

まで入力してタブキーを押すと、次のように候補のディクショナリが表示されます。

SQL> SELECT * FROM DBA_U
 DBA_UNDO_EXTENTS       DBA_UPDATABLE_COLUMNS  DBA_USERS_WITH_DEFPWD
 DBA_UNUSED_COL_TABS    DBA_USERS

うまく使いこなすことで、タイプミスや調べる時間を大幅に削減できます。入力補完のファイルはテキスト形式なので、バージョンに応じて自分で作ることもできます。

おわりに

今回はrlwrapを使用する方法を説明しました。それ以外にもOracle SQL Developerの開発チームが作成しているSQLclというツールもあります。こちらはSQL*Plusの機能拡張版で、今回説明したヒストリー/入力補完機能があるだけでなく、大幅な機能強化が施されています。

SQLcl は、Oracle SQL Developer 4.1のページからダウンロードできます(2015年6月時点ではEarly Adopterバージョン)。JavaプログラムなのでJDKのインストールは必要ですが、Oracle Net等のOracleクライアントは不要です。詳細はダウンロードページや以下のWebサイトをご覧ください。

SQLcl ダウンロードページ

にわかワイン通養成講座

第5回 ワインの値段(1)

いろいろなワインを飲みたいと思ったときに悩ましいのが、ワインの値段です。ちょっとしたスーパーでも、500円程度のものから数千円のものまで並んでいます。専門店に行けば、数万円は当たり前です。もっとも高価で、もっとも有名なワイン「ロマネコンティ」は100万円前後で流通しています。

自宅や居酒屋で飲むような1本千円前後のワインでさえ、ビールや缶チューハイと比べると高いのに、なぜそんなに高いか不思議ではありませんか? わたしもワインを意識的に飲み始めた当初は、2千円のワインを買うのにも勇気がいりました。今回はワインの値段について考えてみます。

ワインが高い理由はいくつかあります。代表的な理由は次の2つでしょうか。

  • ほかのお酒と比べて農産物的な側面が強く工業化が難しいこと。
  • 有名銘柄は生産量が限られているにもかかわらず、世界的な需要があること(需要と供給のバランス)。

理由を説明する前に、お酒の種類の分類について説明します。次の表を見てください。お酒は大きく分けて、醸造酒と蒸留酒に分けられます。さらに醸造酒は、果実を使用したものと、穀物を使用したものがあります。ワインは、果実を原料とした醸造酒に分類されます。

醸造酒
原料を酵母で発酵した酒
果実原料 ワイン、シードルなど
穀物原料 日本酒、ビール
蒸留酒
醸造酒を蒸留器で蒸留した酒
果実原料 ブランデー、アップル・ブランデー
穀物原料 ウイスキー、バーボン、焼酎、ウォッカ
混成酒
醸造酒や蒸留酒に、ほかの副原料を配合したもの
リキュール、みりん、合成清酒

1つ目の理由は醸造方法によるものです。ワインは原則として、その年に収穫された、その地域のブドウだけから造られます。ブドウは年に1回しか収穫できず、保存はできません。またブドウの収穫量は年によって大きく異なります。悪天候や病気で半分以下になってしまうことも珍しくはありません。そのため穀物原料を使ったお酒のように、大規模な工業化は困難です。濃縮果汁を希釈したブドウジュースからワインを醸造する方法もあるのですが、世界的にはマイナーな方法なので説明から除外します。

2つ目の理由は、需要と供給の関係です。高級ワインの多くは自社農園のブドウだけで造られています(シャンパンを除く)。そのため高級ワインの生産量は所有する畑の大きさに依存します。それに対して穀物を原料とした酒の多くは外部から原材料を購入するので、生産量は醸造設備に依存します。

たとえばロマネコンティの生産量は年間約6000本です。生産量が多いと言われるボルドーの1級シャトーでも年間の生産量は20万本から40万本程度です。これらに世界中から買い手が付くのですから、高くなってしまうのは仕方のないことです。日本酒や焼酎でも、レア銘柄にプレミア価格が付いているのと同じです。

ワインの値段と世界の経済には大きな関係があり、近年は中国やロシアなどの経済成長とともに急な値上がりをしています。今では5万円以上するボルドーの1級シャトーでも、15年前は1万円台で買えたこともありました。ただし大きく値上がりしたのは、銘醸ワインと呼ばれる一部のワインだけです。

では、同じワインでも、なぜ大きく値段が違うのでしょうか。これについては次回取り上げます。



第5回 SQL*Plusを使いやすくする