見出し画像

シェルからSQL実行する(h2database-01,MAC,zsh,Java19)

概要

h2database  でコマンドラインからSQLを指定して実行する。
Apache Derby付属ijで実行hsqldb付属sqltool.jarで実行と同等機能の確認。

本質とは関係ないが、コマンドプロンプトに実行シェル(Macの場合zsh)を表示するように変更した上で、H2databaseのjarファイルの保管ディレクトリを環境変数に設定する。

 ~ % PS1="%N %# "
-zsh % H2DRIVERS=~/Downloads/h2/bin

hsqldbで使用したSQL文をorg.h2.tools.Shellの機能を呼び出して実行してみる。

-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "select 5+4*3/2-1 from (values(0));"
10
10
(1 row, 74 ms)

h2databaseではijやsqltoolのような独立ツールでなく、データベース機能と一体になっているAll-In-Oneなファイル1つで実行できるような実装が興味深い。
尚、org.h2.tools.Shellを使った上記の方法とは別のorg.h2.tools.RunScriptを使用した別解もある。

-zsh % echo "select 5+4*3/2-1 from (values(0));" | java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.RunScript -url jdbc:h2:mem:. -script /dev/stdin -showResults
select 5+4*3/2-1 from (values(0));
--> 10
;%

出力内容が異なるので環境変数への設定など事後処理への設定時はそれぞれに合わせた対応が必要になる。

-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "select 5+4*3/2-1 from (values(0));" | sed -n 2P
10
-zsh % echo "select 5+4*3/2-1 from (values(0));" | java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.RunScript -url jdbc:h2:mem:. -script /dev/stdin -showResults | grep ^-- | cut -c 5- 
10

ちなみにh2databaseのこれらの機能は、コマンドラインで指定されたSQL文がセミコロンで終端されていない場合、自動で補完して解釈してくれるようである。

-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "select 5+4*3/2-1 from (values(0))"           
10
10
(1 row, 75 ms)
-zsh % echo "select 5+4*3/2-1 from (values(0))" | java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.RunScript -url jdbc:h2:mem:. -script /dev/stdin -showResults 
select 5+4*3/2-1 from (values(0))
;
--> 10
;%

このせいなのか、org.h2.tools.RunScript実行時は出力内容にセミコロンだけの行が1行余計に出てしまうので、実行結果だけに編集する際に、2行目を意味する sed -n 2Pでなく、先頭が--で始まる行の取得である grep ^-- を使用している。

Valuesを単体使用する構文はhsqldbと同様に有効である。この場合適当な列名がない場合のカラム名としてC1(おそらく「カラム1」の意味)を出力するorg.h2.tools.Shellが、SELECT構文での選択列名に特に計算値の出力の場合に計算結果(つまりSQLの実行結果とこの場合同じもの)が出力されるorg.h2.tools.RunScriptの-showResults出力の場合よりわかりやすい場合もあるかもしれない。

-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "values(5+4*3/2-1);"                           
C1
10
(1 row, 104 ms)
-zsh % echo "values(5+4*3/2-1);" | java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.RunScript -url jdbc:h2:mem:. -script /dev/stdin -showResults 
values(5+4*3/2-1);
--> 10
;%

DUAL表を使用するORACLE風のSELECT構文は、(ORACLEもしくはDS2互換構文指定が必要なhsqldbと異なり)標準で動作する。

-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "select 5+4*3/2-1 from DUAL;"
10
10
(1 row, 83 ms)
-zsh % echo "select 5+4*3/2-1 from DUAL;" | java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.RunScript -url jdbc:h2:mem:. -script /dev/stdin -showResults
select 5+4*3/2-1 from DUAL;
--> 10
;%

FROM句を省略するMSSQLserver(もしくはMYSQL、POSTGRESQLSQL)風のSELECT構文も同様に標準で動作する。

-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "select 5+4*3/2-1;"                                                
10
10
(1 row, 116 ms)
-zsh % echo "select 5+4*3/2-1;" | java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.RunScript -url jdbc:h2:mem:. -script /dev/stdin -showResults 
select 5+4*3/2-1;
--> 10
;% 

列名をヘッダ出力したい場合や実行所要時間を表示したい場合はorg.h2.tools.Shell,
実行SQLを出力したい場合はorg.h2.tools.RunScriptであろうか。

しかし、たったこれだけの事だが、標準と違う動作させる時には明示的に互換構文設定を指定しないとエラーにするhsqldbと、設定しなくともサポートする各種SQL方言を動作させるh2databaseの設計思想的な対比が興味深い。

実行環境

-zsh % sw_vers
ProductName:		macOS
ProductVersion:		13.2
BuildVersion:		22D49
-zsh % zsh --version
zsh 5.8.1 (x86_64-apple-darwin22.0)
-zsh % java -version
openjdk version "19.0.2" 2023-01-17
OpenJDK Runtime Environment Homebrew (build 19.0.2)
OpenJDK 64-Bit Server VM Homebrew (build 19.0.2, mixed mode, sharing)
-zsh % echo ${PS1}
%N %# 
-zsh % java -cp ${H2DRIVERS}/h2-2.1.214.jar org.h2.tools.Shell -url jdbc:h2:mem:. -sql "values(h2version());"
C1
2.1.214
(1 row, 67 ms)

参照

MacOS環境でJavaを使用する
MacOS環境のJavaでhsqldbを使用する
シェルからSQL実行する(Apache Derby-01,MAC,zsh,Java19)
シェルからSQL実行する(hsqldb-01,MAC,zsh,Java19)

この記事が気に入ったらサポートをしてみませんか?