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

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


ユーザー定義型

 SQL99では、社員、プロジェクト、金額、画像、文章などさまざまなアプリケーションに即した型を、ユーザーが自由に定義することが可能になった。 ユーザー定義型(UDT:User Defined Type)には、DBMSが提供する組込みデータ型の1個をもとに、新たなデータ型を生成するユーザー定義DISTINCT型と、そのユーザー定義DISTINCT型を含む複数の任意の型を組み合わせて、新たに1つの型を生成する構造型(structured type)とがある。

  ユーザー定義型に加えて、SQL文の中に使用できる関数を自由に定義することもできるようになった。そこでここでは、ユーザー定義型のうち、まず基本的なユーザー定義DISTINCT型を説明し、ついでユーザー定義関数の概要を説明する。そのあとでオブジェク・トリレーショナルの真髄とも言うべきユーザー定義構造型に話を進めていきたい。

■ユーザー定義DISTINCT型

 図16は、商品表の円価格列とドル価格列を、システム提供の組込みデータ型であるDECIMAL型で定義している。例えば円価格列をドル価格列で更新するというような、意味のない操作をユーザが誤ってDBMSに要求したとしても、DBMSは正常な要求として更新を行ってしまう。それは意味の違う列を互換な組込み数値型を「借用して」定義しているためで、列本来のデータ型、ここでは円型とドル型に即した型チェックをDBMSでは行えないからである。

図16 金額を組込み数値型で定義した場合の問題

 円価格列とドル価格列を別の型として定義するCREATE TYPE文の例を図16に示す。ここでは円を意味するJPN_YEN型を組込みDECIMAL型を元に定義し、USドルを意味するUS_DOLLAR型を組込みDECIMAL型を元に定義した。DECIMAL型に別名を付けたに過ぎないように見えるが、これによってJPN_YEN型の円価格列とUS_DOLLAR型のドル価格列とは非互換となり、いかなる誤った比較や演算も防ぐことができる。言い替えれば、組込みデータ型の名前をアプリケーションでの意味に即した型の名前に変換したことになり、より強い型チェックを行うことができるのである。

 しかし円価格を円ドル換算レートによってドル価格に換算したい場合があるだろう。そのときは、CAST関数を使用して共通で互換なデータ型に変換すれば、異なる型の間でも比較や演算を行うことができる。図17の例では、ドル価格列のUS_DOLLAR型をDECIMAL型に変換してから120円を乗じ、その値をさらにJPN_YEN型に変換してから円価格列に代入している(備考:CAST関数は、SQL92においてサポートされている)。

図17 ユーザ定義DISTINCT型の例

 このようにしてSQL99の利用者は、組込みデータ型を元に、柔軟で強力な型チェックが行えるデータ型を無限に手にすることができる。


ユーザー定義関数

 SQL99のもとでは、次の3種類のユーザ作成のプログラムコード(SQLではそれらを「ルーチン」と総称している)を起動する手段が提供されている。

  • プロシージャ(ストアドプロシージャとも呼ばれる)
  • 関数
  • メソッド

 これらはそれぞれ、CREATE PROCEDURE文、CREATE FUNCTION文、そしてCREATE METHOD文によってルーチンの名前と引数と内部処理ロジックを定義する。定義したプロシージャはCALL文によって呼び出すが、関数とメソッドはデータ操作文(SELECT、INSERT、UPDATE、DELETE)の中から呼び出す。ここでは、ユーザー定義の関数について説明する。メソッドについては後述するユーザ定義構造型の中で触れる。ユーザー定義関数の例を図18に示す。

図18 ユーザー定義関数の例

 1番目の例は、顧客コードを引数として渡された関数が、その顧客コードを条件にして顧客口座表から残高と利息を求め、その和を計算して関数の戻り値として返却する。簡単な例なので、この程度の計算ロジックであればSELECT文に直接書いてもたいしたことがないように見えるが、さらに複雑な処理を行いたい場合、ユーザ定義関数は威力を発揮する。SQL設計者は、関数のインタフェースだけを知ればよく、その処理ロジックの詳細を知ることなく、複雑な処理をSQL上で行うことができるようになるだろう。またここで注目していただきたいのはルーチンの処理ロジックを、「永続格納モジュール」と呼ばれる、SQL標準で規格化されている手続き文を使用してBEGIN句からEND句の間に記述していることである。これを特に「SQLルーチン」と呼ぶが、SQLルーチンを使用すれば、DBMS製品や稼動環境に依存しないユーザー定義関数を開発することができる。

 2番目の例は、ユーザ定義関数が、C言語やCOBOL言語のようなプログラミング言語を使用して作成した外部ルーチンを呼び出すことができることを示している。複雑な処理を行う様々な関数を開発し、それらをライブラリとして提供するならば、そのDBMS上でユーザー定義関数を定義さえすれば、高度なアプリケーションでも容易に導入することができるだろう。実際、国際標準であるSQL/MM(multimedia)は、マルチメディアアプリケーションをユーザー定義関数と外部ルーチンのライブラリ提供によって普及させようとの狙いがある。

 関数の引数の受け渡しは自由に設計できるが、PARAMETER STYLEのオプションとしてSQLを選択して、SQLによって決められた形式で引数を受け渡す場合は、引数にナル標識を与えることもできる(例えば、SELECT文を発行して得た列値が有効かどうかをナル標識で識別するように、引数のデータについても同様の目的で区別することができる)。

 ユーザ定義関数を呼び出すには、データ操作文の中の式の一部として記述すればよい。次にその例を示す。

SELECT 顧客コード, get_balance(顧客コード)
FROM 顧客口座表;

結果行としては、顧客ごとの残高に利息を足した新残高のリストが得られるだろう。


関数のオーバロード

 多数の関数を定義していくと、無修飾の関数名の中には同じ名前が存在し得る。次の例のS1とS2は、関数Fのスキーマであり、括弧内は引数を表わすものとする。

S1.F ( p1 INT, p2 REAL )
S1.F ( p1 REAL, p2 INT )
S2.F ( p1 INT, p2 REAL )

 もしある関数を呼び出したいたいとき、同じスキーマで同じ関数名のものが存在する場合、同じシグネチャ(引数の数が同じで、引数のデータ型が同じもの)の関数が選ばれる。
また、もし同じシグネチャを持つ関数が存在する場合は、スキーマが同じ関数が選ばれる。このようにユーザ定義関数については関数のオーバロードがサポートされる。

とびら 新しい業界標準「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
  イテレータの使用
  SQLデータ型としてのJavaクラス
オブジェクトリレーショナル機能の応用例
  SQL/MM全文検索(フルテキスト)
  SQL/MM地理情報(スペーシャル)
今後のSQL標準化動向
  コレクション型の拡張
  オブジェクトリレーショナル機能の拡張
  SQL/MED
  OLAP機能の拡張
  自由度が高まるデータアクセス



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


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

注目のテーマ

Master of IP Network 記事ランキング

本日 月間