6.5.1 抽象データ型の定義
抽象データ型とルーチンを使用して,複雑な構造を持つデータ型とその操作を独自に定義し,利用できます。
(1) 定義方法
任意の構造を持つデータ型(抽象データ型)を定義するには,定義系SQLのCREATE TYPEを実行します。CREATE TYPEでは,データ構造とそのデータに対する操作を定義します。ここでは,次に示すデータ構造を持つ抽象データ型「t_従業員」を定義し,それに対する操作を関数として定義します。
- データ構造
-
-
氏名,性別,役職,入社年月日,顔写真,基本給というデータ構造を定義します。
-
- データ操作
-
-
現在の日付と入社年月日から勤続年数を算出します。
-
勤続年数に応じた報酬率を算出します。
-
基本給に報酬率を乗じて従業員の報酬を算出します。
-
- (例)
CREATE TYPE t_従業員 ( …1 PUBLIC 氏名 NCHAR(16), 性別 CHAR(1), 役職 NCHAR(10), PRIVATE 入社年月日 date, …2 PUBLIC 顔写真 BLOB(64K), PROTECTED 基本給 INTEGER, …3 PUBLIC FUNCTION t_従業員(p_氏名 NCHAR(16), …4 p_性別 CHAR(1), p_役職 NCHAR(10), p_入社年月日 date, p_顔写真 BLOB(64K), p_基本給 INTEGER) RETURNS t_従業員 BEGIN DECLARE d_従業員 t_従業員; …5 SET d_従業員=t_従業員(); …6 SET d_従業員..氏名=p_氏名; …7 SET d_従業員..性別=p_性別; …7 SET d_従業員..役職=p_役職; …7 SET d_従業員..入社年月日=p_入社年月日; …7 SET d_従業員..顔写真=p_顔写真; …7 SET d_従業員..基本給=p_基本給; …7 RETURN d_従業員; …8 END, PUBLIC FUNCTION 勤続年数(p t_従業員) RETURNS INTEGER …9 BEGIN DECLARE working_years INTERVAL YEAR TO DAY; SET working_years=CURRENT_DATE - p..入社年月日; RETURN YEAR(working_years); END, PROTECTED FUNCTION 報酬率(p t_従業員) RETURNS FLOAT …10 BEGIN DECLARE rate FLOAT; SET rate=勤続年数(p)*0.2/30; RETURN rate; END, PUBLIC FUNCTION 報酬(p t_従業員) RETURNS INTEGER …11 BEGIN DECLARE bonus INTEGER; SET bonus=p..基本給*報酬率(p); RETURN bonus; END )
- 〔説明〕
-
-
データ構造の定義です。抽象データ型「t_従業員」を定義します。
-
「t_従業員」型の属性「入社年月日」は,報酬査定の算出に使用します。この属性は,外部から直接参照又は変更する必要がないため,隠蔽レベル「PRIVATE」を指定しています。隠蔽レベルについては,「抽象データ型を含む表」を参照してください。
-
「t_従業員」型の属性「基本給」は,報酬査定の算出に使用します。この属性も,外部から直接参照又は変更する必要がありません。ただし,この属性はサブタイプでも共通に参照するため,隠蔽レベル「PROTECTED」を指定しています。隠蔽レベルについては,「抽象データ型を含む表」を参照してください。
-
値(インスタンス)を生成し,関数の戻り値とするためのSQL変数をt_従業員型で宣言します。
-
システムが提供するデフォルトコンストラクタ関数によって,すべての属性の値がナル値である値(インスタンス)を生成します。デフォルトコンストラクタ関数は,引数なしのt_従業員型と同じ名称の関数です。
-
6.で指定した値に対し,コンポネント指定による代入文で,各属性の値を代入します。コンストラクタ関数の引数から得た値を設定したり,その値を使ってデータを加工したものを代入したりできます。
-
RETURN文によって,新しく生成した値(インスタンス)を戻り値とします。戻り値のデータ型は,t_従業員型でなければなりません。これは,抽象データ型名と同じ名前のコンストラクタ関数であること及びRETURNS句で型を決めているためです。
-
データ操作のための関数です。従業員の勤続年数を返します。現在の日付と入社年月日から算出します。隠蔽レベル「PRIVATE」が指定されている属性「入社年月日」にアクセスする関数です。
-
データ操作のための関数です。従業員の報酬率を返します。勤続年数に応じて算出します。
-
データ操作のための関数です。従業員の報酬を返します。基本給に報酬率を乗じて,勤続年数に応じた従業員の報酬を算出します。
-
(2) 継承を利用する場合の定義方法
抽象データ型「t_従業員」をスーパタイプとするサブタイプ「t_営業部員」の定義例を次に示します。
- (例)
CREATE TYPE t_営業部員 UNDER t_従業員 ( PUBLIC 担当顧客 NCHAR(15), PUBLIC FUNCTION 報酬(p t_営業部員) RETURNS INTEGER BEGIN DECLARE salebonus INTEGER; SET salebonus = 顧客総数(・・・)*1000+p..基本給*報酬率(p); RETURN salebonus; END )
(4) 抽象データ型のサブタイプを削除する方法
表定義で,ある抽象データ型を直接指定していない場合でも,その抽象データ型の上位の抽象データ型(スーパタイプ)が列の型に指定されている場合,代替可能性によってその抽象データ型(サブタイプ)の値は表に格納されている場合があります。このため,抽象データ型(サブタイプ)を削除する場合には注意が必要です。
次の図に示す代替可能性を利用した抽象データ型を含む表の場合にサブタイプを削除する方法について説明します。
-
社員表を削除します。
-
t_従業員のサブタイプ「t_営業部員」を削除します。
-
t_従業員を削除します。
-
t_A社従業員のサブタイプ「t_A社営業部員」を削除します。
-
t_A社従業員を削除します。
抽象データ型のサブタイプを削除できないケースについては,「注意」を参照してください。
(5) 注意
-
コンストラクタ関数を指定して値を生成している場合,抽象データ型を構成する各属性の値がナル値であっても,抽象データ型全体としての値はナル値にはなりません。
-
ある抽象データ型及びそのスーパタイプが表で定義されている場合,その抽象データ型のサブタイプは削除できません。
-
ある抽象データ型及びそのスーパタイプが,ほかの抽象データ型の属性に指定されている場合,その抽象データ型のサブタイプは削除できません。
-
サブタイプを定義する場合,作成するデータ型の上位のデータ型に次に示す条件を満足するストアドプロシジャ及びストアドファンクションがあると,それらは無効状態になります。
-
ストアドプロシジャ及びストアドファンクションのSQLパラメタに指定したデータ型
-
関数の戻り値のデータ型
-
ストアドプロシジャ及びストアドファンクションから呼び出している関数の引数及び戻り値のデータ型
-
ストアドプロシジャ及びストアドファンクション中で指定しているデータ型(コンポネント指定で抽象データ型をアクセスする場合,その途中のデータ型を含みます)
-