オブジェクト指向、Javaを取り入れた
新しい業界標準「SQL99」詳細解説

第三章 SQLJと今後の標準化動向(2)


静的埋め込みSQLを実現する「SQLJ」

 SQL99を構成する規格の1つに、OLB(オブジェクト言語バインディング:Object Language Binding)があリ、すでに業界標準になりつつあるSQLJを国際標準化しようと検討している。

 SQLJはJavaプログラムから静的埋め込みSQLを使用するためのメソドロジーと仕様である。 静的埋め込みSQLの実行を提供するので、サーバーでの負荷が軽減し、Javaプログラムによる大量のクライアント処理やトランザクション処理の実現を可能にするという意味で、非常に重要性が高いと言える。

■パフォーマンスの向上と移植性

 SQLJの最も注目すべき点は、やはり静的SQLによるパフォーマンスの向上である。図33は動的SQLと静的SQLの実行時のプロセスの差を示したものである。動的SQLの場合は、実行時にSQL文や権限のチェック、アクセスパスの決定を行うばかりでなく、JavaとSQLのデータ型の変換が必要である。それに比べ静的SQLの場合は、上記の各プロセスのほとんどを省くことができる。ただし、SQLJはJDBCを全て置き換えるものではない。SQLJは静的SQLの記述のために使用するものであり、動的SQLを記述したい場合は従来どおりJDBCを使用する。またSQLJとJDBCは同じデータベースへの接続コンテキストを共有可能であり、1つのプログラムの中で共存可能である。

図33 動的SQLと静的SQLの実行時処理の相違点

 SQLJの第二の特徴はプログラムの移植性(ポータビリティ)である。ただし、この静的SQLプログラムの移植性という概念は特に新しいものではない。われわれはそれをC言語において追求してきた。しかしC言語であっても完全な移植性はなく、各プラットフォームでの特有な言語フィーチャーがあったり、また各DBMSベンダーは固有の実行時コードを必要とする実装になっており、それらが移植性を阻害する要因となっていたのである。

 しかしSQLJでは実行時に各DBMS用のカスタム・プロファイルをロードするようなプリコンパイラのフレームワークを提供することにより、これらの問題を解決したの。つまり、プリコンパイルされたプログラム(Java バイトコードと呼ばれる)は、どのDBMSに対しても実行可能なのである。

■SQLJのコンパイル

 図34はSQLJプログラムのコンパイルの手順を示したものである。

図34 SQLJプログラムのコンパイル手順

 従来の埋め込み型SQLプログラムを作成する場合も、プリコンパイル、コンパイル/リンク、バインドという複数のステップが必要であったが、SQLJでも図34のようにいくつかのステップがある。

 まず最初のステップ1は、従来のプリコンパイル機能に類似したトランスレートという作業である。トランスレータはSQLJソースコードをJavaソースコードに変換するのと同時に、SQL文部分を抽出したプロファイルというものを作成する。もしSQLJプログラムが複数のデータベース接続コンテキストを含んでいる場合は、そのコンテキストの数だけプロファイルが作成される。

 次のステップ2は、通常のJavaのコンパイルステップと同じであり、1で書き出されたJavaソースコードをJavaのバイトコードに変換する。

 最後のステップ3は1で作成されたプロファイルをデータベースに対してバインド(カスタマイズ)するステップである。ここで各DBMSごとにSQL文を実行するためのJavaバイトコードを含む、カスタマイズされたSQLJプロファイルが作成される。つまりステップ2まではプラットフォームや製品を問わない標準で規定された仕様に基づいた処理であるが、3のカスタマイザーは各製品固有の仕様に任されているため、カスタマイズ後のプロファイルの内容や実行時における静的パッケージの呼び出し方法は、製品固有の実装となっている。

■SQLJの記述方法

  Javaはオブジェクト指向的な言語なので、JDBCを使用する場合もオブジェクトを生成し、そのリファレンスを経由してオブジェクトが持つメソッドを実行するという方法をとる。そのためにアプリケーション開発者はSQL言語だけでなくオブジェクトの生成、呼び出すメソッドの種類などにも精通している必要があった。

 一方SQLJでは、従来の埋め込み型SQLが“EXEC SQL”後に実行したいSQL文を記述する構文形式となっているのと同じように、SQLJでもSQLJ句と呼ばれる記述方法( #sql で始まり、;で終了する)を採用している。このため従来からの埋め込みSQLのプログラミング知識を生かすことが可能であり、またJDBCのようにメソッドの呼び出しのコーディングが不要である。従ってJDBCよりも開発工数が少なく、また読みやすいプログラムの記述が可能である。そのことは次に挙げる例文をご覧になれば、ご理解いただけると思う。

■SQLJ対JDBC

 以下は単一行のSELECT文の例である。JDBCではPREPARE,OPEN,FETCH,CLOSEの4ステップが必要となる処理を、SQLJではたった1行で記述できる。また結果の値もgetStringのようなメソッドを使用せず、直接ホスト変数(:addr)に得ることが可能である。最初の例では単一行INSERT文の例、次の例は、ストアドプロシージャを呼び出す場合の例である。


SQLJとJDBCの比較 その1

SQLJ:
#sql [ con] {INSERT INTO 社員表 VALUES ( :hv1,:hv2,:hv3) };

JDBC:
CallableStatement mystmt = con.prepareCall("INSERT INTO 社員表 VALUES(?,?,?);
mystmt.setString(1,hv1);
mystmt.setString(2,hv2);
mystmt.setString(3,hv3);
mystmt.executeUpdate();


SQLJとJDBCの比較 その2

SQLJ:
#sql [con] { SELECT 住所 INTO :addr FROM 社員表 WHERE 名前 = :name };

JDBC:
java.sql.PreparedStatement ps = con.prepareStatement("SELECT 住所 FROM 社員表 WHERE 名前 = ?");
ps.setString(1, name);
java.sqlResultSet names = ps.execureQuery();
names.next();
name = names.getString(1);
names.close();

 

■イテレータの使用

 SQLJによる単一行SELECT文の例を紹介したが、複数行の結果が返ってくる場合は、SQLJでは結果集合イテレータ(Result Set Iterator)と呼ばれる特殊なJavaオブジェクトを使用する。イテレータとはJDBCのResultSet、またはSQL92での埋め込み型SQLでのカーソルのようなものと考えれば分かりやすい。しかしカーソルと異なる点は、イテレータは第1クラスオブジェクトであるので、パラメータとして他のメソッドに渡したり、そのイテレータを作成したSQLJトランスレーションの単位以外でも使用可能である。イテレータには位置づけイテレータと名前付きイテレータの2種類があり、それぞれ定義の仕方が異なる。

図35 位置づけイテレータの定義と使用例

 図35は位置づけイテレータの定義および使用例である。 位置づけイテレータの場合はイテレータの定義部分ではデータ型のみを記述し、結果セットの列のデータにアクセスするためには、FETCHステートメントとホスト変数を使用する。またフェッチごとに自動的にカーソルが進む。なお、ここで注意すべきことは、イテレータの定義部分でのデータ型の順番と、結果セットの列の順番を一致させるということである。ただし従来の埋め込み型SQLのプログラミングでも、SELECTリストの順序とホスト変数の順序を一致させる必要があったため、これに関しては特に違和感はなく、従来方式のプログラミングに慣れている人にとっては親しみやすい方式である。

図36 名前付きイテレータ

 図36は名前付きイテレータの定義および使用例である。名前付きイテレータの場合はイテレータの定義部分でデータ型と結果列名を記述し、結果セットの列のデータにアクセスするためには、各結果列用に生成されたメソッドを使用する。この方式では、各結果列の値をホスト変数で受け取ることなしに、直接メソッドによってアクセスできるので、イテレータの定義部分でのデータ型および結果列名の順序とSELECTリストの列の順序は異なっていてもよく、またSELECTリストが非常に多い場合などにおけるプログラミングの煩雑さを解消することができる。なお、この方式の場合、カーソルを進めるためにはnext()を使用する。

■SQLデータ型としてのJavaクラス

  さてSQLJの最後のパートとして、SQLデータ型とJavaクラスの対応について触れる。SQLJ ではJavaクラスをSQLデータ型として扱うためのSQL拡張が記述されているが、このパートは国際標準ではまだ検討対象には入っていない。従って概念としての紹介と受け止めていただきたい。

 Javaのクラスは基本的に構造型かBLOBに対応でき、列の定義やSQL99での構造型表の定義に使用できる。またオブジェクトの状態や振る舞いについても対応可能であり、JavaのメソッドはSQL型におけるSQL99メソッドとなる。結果セットのフェッチやメソッドの呼び出しでは自動的な対応づけが行われる。また型の使用権限の取り扱いも含まれている。実際の対応づけは CREATE TYPE構文の拡張を使用するが、その際の対応づけを表6に示す。

表6 JavaとSQLの型の対応

Java SQL
クラス ユーザー定義(構造)型
メンバ変数 属性
メソッド メソッド
コンストラクタ 初期化メソッド
静的メソッド 静的メソッド
静的変数 静的オブザーバメソッド

 SQLの初期化メソッド(initializer method)は、定義された型と同じ名前を持ち、 NEW 演算子を使用して呼び出す。またSQLは静的メンバー変数(static member valiable)を知らないので、静的変数の値を返す静的SQLメソッドに対応づけられる。そのため静的変数の更新はサポートされていない。

 図37はJavaクラスとSQL型の対応の具体例である。ここでは SQLDataというインターフェースを実装した Residence というクラスを Addressという SQLの構造型で対応づけている。

図37JavaクラスとSQL型の対応

 またJavaとSQLではオブジェクトの更新モデルが異なっている。Javaのモデルはオブジェクトベースであり、通常は値を返さないオブジェクトメソッドを通してオブジェクトメンバー変数を更新する。一方SQLのモデルは値ベースであり、オブジェクトのメソッドはオブジェクトの更新後のコピーを返す。また、オブジェクトの更新を永久的なものとするためにはUPDATE文が必要となる。そのためSQLJではJavaメソッドの変更を要求しない対応づけを許している。 すなわちSELF AS RESULTはインスタンスの更新メソッドであることを示すもので、該当の型を結果値として返すメソッドである場合に指定する。

  住所型を列に持つ社員表の更新の例を示す。住所型ではchangeAddressメソッドにSELF AS RESULTが指定されている。

列タイプとしての型の使用:
CREATE TABLE 社員用(
 名前 VARCHAR(40),
 住所 住所型)

オブジェクトの挿入:
INSERT INTO 社員表 VALUES ('田中', NEW 住所型())

オブジェクトの更新:
UPDATE 社員表
SET 住所 = 住所.changeAddress('1234 ベイサイド通り 湾岸市')
WHERE 名前 = '田中'

オブジェクト情報の照会:
SELECT 住所.print()
FROM 社員表
WHERE 住所.city = '湾岸市'

 以上、SQLJの優位性とまたSQLJによるオブジェクト指向とSQLの融和について説明してきた。


とびら 新しい業界標準「SQL99」詳細解説

第一章 高度なデータ操作

SQL99の背景と特徴
SQL99の主な機能強化
  スキーマ定義の新機能
  データ操作と演算子の新機能
  整合性の新機能
  セキュリティ(機密保護)の新機能
  トランザクション管理の新機能
  クライアント/サーバの新機能
高度なリレーショナル操作
  共通表式 WITH句
  再帰SQL
OLAPによる分析手順
  ROLLUP
  CUBE
  GROUPING SETS
ユニオン(UNION)経由の更新
  結合(JOIN)経由の更新


第二章 柔軟さを増したデータ構造

ユーザー定義可能な新しいデータ
  新しい組込みデータ型
  真理値型(BOOLEAN型)
  配列型(ARRAY型)
LOBとは
  LOBデータ型の定義
  LOBデータ型の取り扱い
  LOBロケータの使用
  HOLD LOCATORとFREE LOCATOR
  LOBの挿入(更新)と検索方法の拡張
ユーザー定義型
  ユーザー定義DISTINCT型
ユーザー定義関数
関数のオーバーロード

オブジェクトリレーショナル
  ユーザー定義構造型と列オブジェクト
  ユーザー定義構造型と行オブジェクト
副表(サブテーブル)と継承(インヘリタンス)
  副型を持つ列オブジェクト
  行オブジェクトと経路式
オブジェクトビュー
トリガ


第三章 ストアドプロシージャとSQLJ

クライアント/サーバ環境のための機能強化
  ストアドプロシージャ
  新しいプロシージャ言語
静的埋め込みSQLを実現する「SQLJ」
  パフォーマンスの向上と移植性
  SQLJのコンパイル
  SQLJの記述方法
  SQLJ 対 JDBC
  イテレータの使用
  Javaを使用したストアドプロシージャとUDF
  SQLデータ型としてのJavaクラス
オブジェクトリレーショナル機能の応用例
  SQL/MM全文検索(フルテキスト)
  SQL/MM地理情報(スペーシャル)
今後のSQL標準化動向
  コレクション型の拡張
  オブジェクトリレーショナル機能の拡張
  SQL/MED
  OLAP機能の拡張
  WINDOW句
  自由度が高まるデータアクセス



「Master of IP Network総合インデックス」



Master of IP Network フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Master of IP Network 記事ランキング

本日 月間