技術ブログ
技術ブログ
このエントリは (全部俺) Oracle ACE Director Tanel Poder Advent Calendar 2013 24日目の記事です。
これまで23個のエントリを書いてきましたが、Advanced Oracle Troubleshooting Guideの翻訳を中心にディープの話が多かったので、軽めな話題を取り上げたいと思います 🙂
このスクリプトはSQL*Plusからカラー表示のエスケープシーケンスを出力することで、問合せ結果をカラー表示するものです。
私はUNIX端末に特に詳しいわけではないので、誤ったことを言っていたら申し訳ないのですが、ANSI標準では端末でカラー表示するためのエスケープシーケンスが定義されているようです。
具体的には、"ESC [ 値;...;値m"という文字列を与えると、カラー表示できます。 "値"には以下の数値を指定します。
Text attributes
0 All attributes off
1 Bold on
4 Underscore (on monochrome display adapter only)
5 Blink on
7 Reverse video on
8 Concealed on
Foreground colors
30 Black
31 Red
32 Green
33 Yellow
34 Blue
35 Magenta
36 Cyan
37 White
Background colors
40 Black
41 Red
42 Green
43 Yellow
44 Blue
45 Magenta
46 Cyan
47 White
したがって、SQL*Plusでカラー表示したい場合、上記のカラー表示のエスケープシーケンス文字列を、問合せの結果と返せばOKです。なお、"ESC"は制御記号であり、通常の文字のように'...'で指定できないため、chr(27)の結果として指定します。chr()は文字コードを引数にとり、対応する文字を返す関数です。
例えば、以下のコマンドを実行すると、問合せ結果の文字色を赤(=31)にできます。
SELECT chr(27)||'[31mTest' || chr(27)||'[0m' red_text FROM DUAL;
"["と"m"の間には、";"区切りで背景色や文字修飾を指定できます。例えば、以下のコマンドを実行すると、黄色の背景色(=43)と太字(=1)を指定できます。
SELECT chr(27)||'[1;31;43mTest' || chr(27)||'[0m' bold_red_text_with_blue_bg FROM DUAL;
xterm-color.sqlは階層問合せで、文字色と背景色について8色の組み合わせ、すなわち64通りの組み合わせを表示します。
余談ですが、ちょっと意図がわからないのが、上記出力の後半部分に相当するxterm-color.sqlの以下の箇所です。
: select chr(27)||'[32m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' a , chr(27)||'[33m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' b , chr(27)||'[34m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' c , chr(27)||'[35m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' d , chr(27)||'[36m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' e , chr(27)||'[37m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' f , chr(27)||'[38m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' g , chr(27)||'[39m'||chr(27)||'[1;'||to_char(rownum+29)||'mTest' h from dual connect by level<=8 :
文字色の指定となる32~39の値を指定していますが、あまり意味があるとは思えないのですが・・・ もし意図が分かる方がいらっしゃったら、こっそり教えてください。:-)
xterm-color.sqlは8色のカラー表示をデモするスクリプトでしたが、xterm-color256.sqlは256色(本当は216色、詳細は後述)のカラー表示をデモするスクリプトです。
UNIX端末に特に詳しいわけではないので、誤ったことを言っていたら申し訳ないのですが、XTermでは256カラー表示するためのエスケープシーケンスが定義されているようです。
具体的には、"ESC [ 38;5;値m"という文字列を与えると、256色カラー表示できます。また、"ESC [ 48;5;値m"という文字列を与えると、背景を256色カラー表示できます。 "値"には以下の数値を指定します。
xterm-color256.sql は、16-231の範囲の6x6x6 RGB カラーを一覧表示します。したがってファイル名に反して、実際には216色を表示します 😛 。
xterm-color256.sql の実装は、すこし工夫が凝らされています。
[oracle@l64rw3 ~]$ cat sql/demos/xterm-color256.sql -- oracle 11.2+ SELECT LISTAGG (CHR(27)||'[48;5;'|| <== (*3) ( 16 + MOD(r,6) + MOD(TRUNC(r/6),6)*6 + MOD(TRUNC(r/36),6)*6*6 )||'m'|| <== (*2) LPAD(16 + MOD(r,6) + MOD(TRUNC(r/6),6)*6 + MOD(TRUNC(r/36),6)*6*6,4)|| CHR(27)||'[0m' ) WITHIN GROUP (ORDER BY MOD(TRUNC(r/6),6)) <== (*3) FROM (SELECT rownum r FROM dual CONNECT BY LEVEL <= 216) <== (*1) GROUP BY MOD(TRUNC(r/36),6) <==(*3) /
(*1)の箇所でで1~216の結果セットを得て、(*2)の箇所で16 + Green + Blue + Redの色コードを得ています。(*3) の LISTAGG ( ... ) WITHIN GROUP (ORDER BY MOD(TRUNC(r/6),6)) GROUP BY MOD(TRUNC(r/36),6)の箇所で、Red系列(MOD(TRUNC(r/36),6))でグループ化して、LISTAGG() 分析ファンクションで文字列結合しています。LISTAGG() は11.2より導入された、複数行の文字列を文字列結合する分析ファンクションです。イメージとしては、スクリプト言語のjoin()に近い動作をします。(よけい分かりにくい? :-P)
実行結果は以下のようになります。なかなかカラフル!