3.4 ユーザー定義のPL/SQLサブタイプ
PL/SQLではユーザー独自のサブタイプを定義できます。
ベース型は、CHAR、DATEまたはRECORDなどのスカラーまたはユーザー定義のPL/SQLデータ型指定子です(事前に定義したユーザー定義のサブタイプが含まれます)。
ノート:
このトピック内の情報は、ユーザー定義のサブタイプおよび「PL/SQLの事前定義のデータ型」にリストされている事前定義のサブタイプの両方に適用されます。
サブタイプの役割は次のとおりです:
-
ANSI/ISOデータ型との互換性の提供
-
その型のデータ項目の使用意図の提示
-
範囲外の値の検出
ここでのトピック
3.4.1 無制約のサブタイプ
無制約のサブタイプには、そのベース型と同じ値セットが含まれているため、ベース型の別名にすぎません。
したがって、同じベース型の無制約のサブタイプは互換性があり、そのベース型との互換性もあります。データ型の変換は発生しません。
無制約のサブタイプを定義するには、次の構文を使用します。
SUBTYPE subtype_name IS base_type
subtype_nameおよびbase_typeの詳細は、subtypeを参照してください。
無制約のサブタイプの例を示します。これは、ANSIとの互換性のためにPL/SQLで事前定義されているものです。
SUBTYPE "DOUBLE PRECISION" IS FLOAT
例3-7 使用意図を示すユーザー定義の無制約のサブタイプ
この例では、制約なしのサブタイプであるBalanceおよびCounter型それぞれのデータ項目の使用意図を示しています。
DECLARE SUBTYPE Balance IS NUMBER; checking_account Balance(6,2); savings_account Balance(8,2); certificate_of_deposit Balance(8,2); max_insured CONSTANT Balance(8,2) := 250000.00; SUBTYPE Counter IS NATURAL; accounts Counter := 1; deposits Counter := 0; withdrawals Counter := 0; overdrafts Counter := 0; PROCEDURE deposit ( account IN OUT Balance, amount IN Balance ) IS BEGIN account := account + amount; deposits := deposits + 1; END; BEGIN NULL; END; /
3.4.2 制約付きサブタイプ
制約付きサブタイプには、そのベース型の値のサブセットのみが含まれています。
サイズ、精度と位取り、または値の範囲を指定できるベース型の場合は、そのサブタイプにもこれらを指定できます。次に、サブタイプを定義する構文を示します。
SUBTYPE subtype_name IS base_type { precision [, scale ] | RANGE low_value .. high_value } [ NOT NULL ]
この構文を使用しない場合、サブタイプに指定されるのはNOT NULL制約のみです。
SUBTYPE subtype_name IS base_type [ NOT NULL ]
ノート:
値の範囲を指定できるベース型は、PLS_INTEGERとそのサブタイプ(事前定義とユーザー定義の両方)のみです。
制約付きサブタイプは暗黙的にベース型に変換されますが、ベース型を制約付きサブタイプに暗黙的に変換できるのは、値がサブタイプの制約に違反していない場合のみです。
制約付きサブタイプは、変換元の値が変換先のサブタイプの制約に違反していない場合のみ、同じベース型を使用する別の制約付きサブタイプに暗黙的に変換できます。
例3-8 範囲外の値を検出するユーザー定義の制約付きサブタイプ
この例では、制約付きサブタイプBalanceを使用して範囲外の値を検出します。
DECLARE SUBTYPE Balance IS NUMBER(8,2); checking_account Balance; savings_account Balance; BEGIN checking_account := 2000.00; savings_account := 1000000.00; END; /
結果:
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: number precision too large
ORA-06512: at line 9
例3-9 同じベース型を使用する制約付きサブタイプ間の暗黙的な変換
この例では、3つの制約付きサブタイプに同じベース型が使用されています。最初の2つのサブタイプは、3番目のサブタイプに暗黙的に変換できますが、相互には変換できません。
DECLARE SUBTYPE Digit IS PLS_INTEGER RANGE 0..9; SUBTYPE Double_digit IS PLS_INTEGER RANGE 10..99; SUBTYPE Under_100 IS PLS_INTEGER RANGE 0..99; d Digit := 4; dd Double_digit := 35; u Under_100; BEGIN u := d; -- Succeeds; Under_100 range includes Digit range u := dd; -- Succeeds; Under_100 range includes Double_digit range dd := d; -- Raises error; Double_digit range does not include Digit range END; /
結果:
DECLARE * ERROR at line 1: ORA-06502: PL/SQL: numeric or value error ORA-06512: at line 12
3.4.3 同じデータ型ファミリ内のベース型を使用したサブタイプ
同じデータ型ファミリ内の異なるベース型が2つのサブタイプに使用されている場合は、変換元の値が変換先のサブタイプの制約に違反していない場合のみ、一方から他方へ暗黙的に変換できます。
データ型ファミリでグループ化された事前定義のPL/SQLのデータ型およびサブタイプは、「PL/SQLの事前定義のデータ型」を参照してください。
例3-10 同じファミリ内のベース型を使用するサブタイプ間の暗黙的な変換
この例では、サブタイプのWordとTextに、同じデータ型ファミリ内の異なるベース型が使用されています。最初の代入文では、Wordの値が暗黙的にTextに変換されます。2番目の代入文では、Textの値が暗黙的にWordに変換されます。3番目の代入文では、Textの値が長すぎるため、値を暗黙的にWordに変換することができません。
DECLARE SUBTYPE Word IS CHAR(6); SUBTYPE Text IS VARCHAR2(15); verb Word := 'run'; sentence1 Text; sentence2 Text := 'Hurry!'; sentence3 Text := 'See Tom run.'; BEGIN sentence1 := verb; -- 3-character value, 15-character limit verb := sentence2; -- 6-character value, 6-character limit verb := sentence3; -- 12-character value, 6-character limit END; /
結果:
DECLARE * ERROR at line 1: ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at line 13