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

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

第三章では、ついにSQLの仕様の一部として採用されたJavaによるサーバプログラミングや、画像や音声なども格納可能なLOB型やユーザーが定義可能なデータ型、そしてオブジェクト機能など、新しいデータ構造を中心に解説する


クライアント/サーバ環境のための機能強化

■ストアドプロシージャ

 ストアドプロシージャは、クライアント/サーバ環境のクライアントがサーバに存在するデータベースを効率よくアクセスするための技術として、すでに多くの製品で実装されている。ストアドプロシージャを使用した場合は、クライアントプログラムからはストアドプロシージャの呼び出しだけになるので、次のような性能上の効果がある。

  • 通信回数が減る。
  • 通信データ量が減る。

これらの効果によってクライアントプログラムの経過時間が短縮し、通信プロトコル変換処理にかかるプロセッサ負荷の削減ができるのである。

  またストアドプロシージャは、データベースサーバ側に格納されるので一元管理に適し、アプリケーションプログラムの部品化と流通を促進する技術としても注目された。しかしストアドプロシージャは製品固有の機能として開発されたので、ベンダ間の移植が事実上困難であるという問題があった。そこでSQL標準は、この問題を解決するために、1996年にストアドプロシージャの内部に書ける構文をプロシージャ言語として標準化し、そしてSQL99がストアドプロシージャを定義するCREATE PROCEDURE文とクライアントプログラムからストアドプロシージャを呼び出すCALL文を正式にサポートすることになったのである。 そのプロシージャ言語とはどのようなものかを簡単に説明したい。

■新しいプロシージャ言語

 従来のSQL92では、埋め込みSQL文を含んだアプリケーションプログラムの構造は、アプリケーションロジックとデータベースをアクセスするSQL文とを明確に分離することを主な目的としていて図2のような構造を想定していた。

図31 SQL92が想定していたアプリケーションプログラムの構造


 SQL文を含むプログラム(図31の右側)の中に記述する構文を特に、モジュール言語と呼んでいて、モジュール言語を実際にどのように既存のプログラミング言語に対応させるかは実装に任されていて、モジュール言語で記述したプロシージャを内部プロシージャとして呼び出すか外部プロシージャとして呼び出すかも、実装に任されている。このプログラム構造の特徴は、プロシージャの開発および呼び出し方が使用するC言語やCOBOL言語などのプログラミング言語の構文に従うので、結果としてそれらのプログラミング言語の稼動環境や言語仕様に依存することになり、特にクライアント/サーバ環境では、標準が目指すSQLアプリケーションの移植性に欠けるという問題があった。

 そこでアプリケーションロジックとSQL文を含むプロシージャのための新しいプロシージャ言語が開発されて、永続格納モジュール(PSM、Persistent Stored Module)と呼ばれる規格にまとめられた。言い替えれば、このプロシージャ言語は、第2章で紹介した「SQLルーチン」と総称して呼ばれる次の3種類のプログラムを記述するための、SQLルーチン専用のプロシージャ言語である。

  • ストアドプロシージャ
  • ユーザー定義関数
  • ユーザー定義メソッド

まず上記のSQLルーチンを定義する文の基本型を図32に示す。

図32 SQLルーチンの呼び出し。SQLルーチン定義文とプロシージャ言語の関係

  ストアドプロシージャと、ユーザー定義関数およびユーザー定義メソッドとの主な相違点は、出力パラメータの個数である。ストアドプロシージャは任意の個数の出力パラメータを定義できるのに対して、後者は関数あるいはメソッドの戻り値としてただ1個を指定する。<ルーチンボディ>の場所には、プロシージャ言語を記述するか、次のようなEXTERNAL句によってDBMS管理外のC言語やCOBOL言語で開発した外部ルーチンを参照することができる。

EXTERNAL NAME 外部ルーチン名

 ルーチンボディには、プロシージャ言語として埋め込みSQL文を記述することができるだけでなく、SQL99では新たに表5に掲げたような文を記述することができる。表5を見てわかるように、まさにプログラミング言語としてロジックの流れを制御することができる。その意味でSQLのプロシージャ言語はまさに手続き言語なのである。

備考:SQLプロシージャ言語だけでアプリケーションを記述できることを目標にしている。その意味でSQLは計算完備な言語を目指していると言える

表5 SQLプロシージャ言語の拡張

複合文 BEGIN ...END;
変数宣言 DECLARE 変数 CHAR(6);
IF文 IF 変数<>'SQL' THEN ... ELSE ... END IF;
CASE文 CASE 変数 WHEN 'SQL' THEN ...ELSE .... END CASE;
LOOP文 LOOP <SQL文のリスト> END LOOP;
WHILE文 WHILE i<100 DO ... END WHILE;
REPEAT文 REPEAT ... UNTIL i<100 END REPEAT;
FOR文 FOR 結果 AS ... DO ... END;
LEAVE文 LEAVE ラベル名 ;
RETURN文 RETURN 戻り値;
CALL文 CALL プロシージャ名(引数1,引数2,引数3);
SET文 SET 変数='abc';
SIGNAL文 SIGNAL 条件名 ;

 複合文は、BEGIN文とEND文との間にはさまれたSQL文をシリアルに実行するが、それにはデータ定義文(例:CREATE TABLE文など)、データ操作文(例:SELECT文など)、動的SQL文、表5の様々な制御文および条件文を記述できて、次のような構造をしている。

ラベル名: BEGIN [ATOMIC | NOT ATOMIC]
DECLARE ローカル変数宣言 ;
DECLARE カーソル宣言 ;
DECLARE ローカルハンドラ宣言 ;
INSERT INTO ...;
UPDATE 表名 SET ...;
...
END ラベル名

 ここで上記の例でBEGIN文のATOMICオプションを指定したとき、処理が途中で失敗した場合はINSERT文とUPDATE文の更新がロールバックされるが、もしNOT ATOMICオプションを指定してUPDATE文が失敗したときはUPDATE文の更新だけがロールバックされる。

 ローカルハンドラ宣言は、例外処理のときに制御を受けるためのものである。次の例は重複キー違反が起きたとき、更新処理を元に戻してハンドラ宣言に記述した複合文を実行することを指定している。

DECLARE dup_key CONDITION
FOR SQLSTATE VALUE ‘21000';
DECLARE UNDO HANDLER FOR dup_key
BEGIN ... END ;

  また、宣言した条件は複合文中の任意の場所でSIGNAL文によって明示的に起こすこともできる。

SIGNAL dup_key ;

 次にプロシージャ言語を使用したストアドプロシージャの定義文の例を示す。

プロシージャ言語で記述したストアドプロシージャの例:

CREATE PROCEDURE upd_interest
( IN kamoku INT,
OUT total_count INT,
total_bal DECIMAL (15,2))
LANGUAGE SQL

BEGIN ATOMIC
 DECLARE kamoku INT DEFAULT 1;
 DECLARE total_count INT DEFAULT 0;
 DECLARE total_bal DECIMAL (15,2);
 DECLARE csr CURSOR FOR
  SELECT 当座残高 FROM 定期預金表;
 SET total_bal=0;

 CASE kamoku
  WHEN 1 THEN
   SET interest_rate=1.003;
   OPEN csr1;
  fetch_loop: LOOP
   FETCH csr1 INTO bal;
   SET total_count=total_count + 1;
   IF SQLSTATE='02000'
    THEN LEAVE fetch_loop1;
   END IF;
  END LOOP
  CLOSE csr1;
 WHEN 2 THEN
  SET interest_rate=1.005;
  ……
 END CASE

内容を順に見ていこう。

  1. ストアドプロシージャを定義する。1個の入力パラメタと2個の出力パラメタのデータ型を指定する
  2. プロシージャ言語を使用することを指定する
  3. ルーチンボディに複合文を記述する。BEGIN文からEND文の間に実行したいSQL文やプロシージャ言語を記述する。複合文中に別の複合文が入れ子になってもよい
  4. DECLARE文によって複合文内で参照するローカル変数を宣言する。変数名が有効な範囲は複合文内である。DEFAULTオプションで既定値を設定することができる
  5. 発行したいSELECT文のためにカーソルを宣言する。5と8は従来の埋め込みSQL文と同じである
  6. SET文を使用して値を変数に割り当てる。COBOL言語のMOVE文に相当する
  7. ここではCASE文を使用して入力パラメタkamokuの値によってロジックの流れを分岐させている
  8. 宣言したカーソルを使ったOPEN文、FETCH文およびCLOSE文を使用して表から結果行を読込む
  9. ここではLOOP文を利用して、SQLSTATEが'02000'(NOT FOUND)になるまでFETCH文を繰り返す。LOOP文の代わりにWHILE文やFOR文を使用して表現することもできる。またここではIF文でSQLSTATEの値を検査している

 このように、プロシージャ言語を利用すれば、データベースをアクセスするアプリケーションプログラムのプログラミング言語を標準化することができて移植性が向上し、製品の市場の流通性が増すことが期待できる。


とびら 新しい業界標準「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 記事ランキング

本日 月間