3 PL/SQLデータ型
PL/SQLの定数、変数、パラメータ、ファンクションの戻り値はすべて、記憶形式および有効な値と演算を決定するデータ型を持っています。
この章では、スカラー・データ型という、内部コンポーネントのない値を格納するデータ型について説明します。
スカラー・データ型にはサブタイプを持たせることができます。サブタイプとは、別のデータ型のサブセットとなるデータ型のことで、その別のデータ型は、そのサブタイプのベース型となります。サブタイプには、そのベース型で有効な演算と同じ演算が含まれています。データ型とそのサブタイプでデータ型ファミリが構成されます。
PL/SQLには、多くの型やサブタイプがパッケージSTANDARDに事前定義されています。また、PL/SQLを使用して、独自のサブタイプを定義することもできます。
PL/SQLのスカラー・データ型は次のとおりです。
-
SQLデータ型
-
BOOLEAN -
PLS_INTEGER -
BINARY_INTEGER -
REFCURSOR -
ユーザー定義のサブタイプ
ここでのトピック
関連項目:
-
コンポジット・データ型の詳細は、「PL/SQLのコレクションおよびレコード」を参照してください
-
REFCURSORの詳細は、「カーソル変数」を参照してください -
スキーマ・レベルのユーザー定義データ型の作成の詳細は、「CREATE TYPE文」を参照してください
-
データ型ファミリごとにグループ化された、事前定義のPL/SQLデータ型とサブタイプは、「PL/SQLの事前定義のデータ型」を参照してください
3.1 SQLデータ型
PL/SQLデータ型にはSQLデータ型が含まれます。
SQLデータ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください(記載されているデータ型およびサブタイプ、データ型の比較のルール、データ変換、リテラル、および書式モデルに関する情報はすべて、次の項目を除き、SQLとPL/SQLの両方に適用されます)。
SQLとは異なり、PL/SQLでは変数を宣言できます。変数には次のトピックが適用されます。
3.1.1 最大サイズの相違
表3-1にリストしたSQLのデータ型は、PL/SQLとSQLで最大サイズが異なります。
表3-1 PL/SQLとSQLで最大サイズが異なるデータ型
| データ型 | PL/SQLでの最大サイズ | SQLでの最大サイズ |
|---|---|---|
|
|
32,767バイト |
2,000バイト |
|
|
32,767バイト |
2,000バイト |
|
|
32,767バイト |
2,000バイト脚注2 |
|
|
32,767バイト |
4,000バイト脚注2 |
|
|
32,767バイト |
4,000バイト脚注2 |
|
|
32,760バイト |
2ギガバイト(GB) - 1 |
|
|
32,760バイト |
2GB |
|
|
128テラバイト(TB) |
(4GB - 1) * |
|
|
128TB |
(4GB - 1) * |
|
|
128TB |
(4GB - 1) * |
脚注1
このデータ型の値の最大サイズをPL/SQLで指定する場合は、定数または変数ではなく、1から32,767の間の値を持つ整数リテラルを使用します。
脚注2
このサイズの違いをなくすには、『Oracle Database SQL言語リファレンス』の手順に従ってください。
脚注3
既存のアプリケーションとの下位互換性を保つためにのみサポートされています。
3.1.2 BINARY_FLOATおよびBINARY_DOUBLEの追加のPL/SQL定数
SQLデータ型のBINARY_FLOATおよびBINARY_DOUBLEは、それぞれ単精度および倍精度のIEEE 754形式の浮動小数点数を表します。
BINARY_FLOATおよびBINARY_DOUBLEの計算では、例外は発生しないため、これらの計算によって生成された値がオーバーフローやアンダーフローなどの状態になっていないかどうか、事前定義の定数と比較して確認する必要があります(例は、『Oracle Database SQL言語リファレンス』を参照してください)。PL/SQLには、この型の定数がSQLよりも多数あります。
表3-2に、BINARY_FLOATおよびBINARY_DOUBLEとして事前定義されているPL/SQL定数を示します。SQLでも定義されているものには注を付けてあります。
表3-2 事前定義のPL/SQLのBINARY_FLOATおよびBINARY_DOUBLEの定数
| 定数 | 説明 |
|---|---|
|
|
条件 |
|
|
単精度の正の無限大 |
|
|
最大正規 |
|
|
最小正規 |
|
|
最大非正規 |
|
|
最小非正規 |
|
|
条件 |
|
|
倍精度の正の無限大 |
|
|
最大正規 |
|
|
最小正規 |
|
|
最大非正規 |
|
|
最小非正規 |
(*) この定数は、SQLでも事前定義されています。
3.1.3 BINARY_FLOATおよびBINARY_DOUBLEの追加のPL/SQLサブタイプ
PL/SQLでは、次のサブタイプが事前定義されています。
-
SIMPLE_FLOAT(SQLデータ型BINARY_FLOATのサブタイプ) -
SIMPLE_DOUBLE(SQLデータ型BINARY_DOUBLEのサブタイプ)
各サブタイプはそのベース型と同じ範囲を取り、NOT NULL制約(「NOT NULL制約」を参照)を含んでいます。
値NULLを取らないとわかっている変数は、BINARY_FLOATまたはBINARY_DOUBLEではなく、SIMPLE_FLOATまたはSIMPLE_DOUBLEとして宣言します。これらのサブタイプを使用すると、NULLかどうかのチェックのためのオーバーヘッドが発生せず、そのベース型を使用するよりパフォーマンスが大幅に向上します。PLSQL_CODE_TYPE='INTERPRETED'よりもPLSQL_CODE_TYPE='NATIVE'を使用する方が、パフォーマンスの向上幅が大きくなります(詳細は、「ハードウェア算術を使用するデータ型の使用」を参照してください)。
3.1.4 CHARおよびVARCHAR2変数
3.1.4.1 長すぎる値の代入または挿入
文字変数に変数の最大サイズより長い値を代入すると、エラーが発生します。次に例を示します。
DECLARE c VARCHAR2(3 CHAR); BEGIN c := 'abc '; END; /
結果:
DECLARE * ERROR at line 1: ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at line 4
同様に、列に挿入した文字変数の値が、定義されている列幅より長い場合も、エラーが発生します。次に例を示します。
DROP TABLE t; CREATE TABLE t (c CHAR(3 CHAR)); DECLARE s VARCHAR2(5 CHAR) := 'abc '; BEGIN INSERT INTO t(c) VALUES(s); END; /
結果:
BEGIN * ERROR at line 1: ORA-12899: value too large for column "HR"."T"."C" (actual: 5, maximum: 3) ORA-06512: at line 4
文字値を変数に代入したり、列に挿入する前に、その文字値から後続する空白を削除するには、RTRIMファンクション(『Oracle Database SQL言語リファレンス』を参照)を使用します。次に例を示します。
DECLARE c VARCHAR2(3 CHAR); BEGIN c := RTRIM('abc '); INSERT INTO t(c) VALUES(RTRIM('abc ')); END; /
結果:
PL/SQL procedure successfully completed.
3.1.4.2 マルチバイト文字の変数の宣言
CHARまたはVARCHAR2変数の最大サイズは、最大サイズを文字数で指定するかバイト数で指定するかに関係なく、32,767バイトです。変数の最大文字数は、キャラクタ・セットのタイプによって、場合によっては文字自体によって異なります。
| キャラクタ・セットのタイプ | 最大文字数 |
|---|---|
|
シングルバイト・キャラクタ・セット |
32,767 |
|
nバイトの固定幅マルチバイト・キャラクタ・セット(AL16UTF16など) |
|
|
文字幅が1とnバイトの間である、nバイトの可変幅マルチバイト・キャラクタ・セット(JA16SJISやAL32UTF8など) |
文字自体によって異なり、32,767(1バイト文字のみを含む文字列の場合)から |
任意のマルチバイト・キャラクタ・セットでn個の文字を常に保持できるように、CHARまたはVARCHAR2変数を宣言する場合は、CHAR(n CHAR)またはVARCHAR2(n CHAR)を使用して、文字数の長さを宣言します(nはFLOOR(32767/4) = 8191を超えることはできません)。
関連項目:
Oracle Databaseのキャラクタ・セットのサポートの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。
3.1.4.3 CHARとVARCHAR2のデータ型の違い
CHARとVARCHAR2のデータ型は、次の点で異なっています。
3.1.4.3.1 事前定義のサブタイプ
CHARデータ型には、PL/SQLとSQLの両方にCHARACTERというサブタイプが1つ事前定義されています。
VARCHAR2データ型には、PL/SQLとSQLの両方にVARCHARというサブタイプが1つ事前定義されており、PL/SQLには、STRINGというサブタイプがもう1つ事前定義されています。
各サブタイプの値の範囲はそのベース型と同じです。
注意:
PL/SQLの今後のリリースでのVARCHARは、新しいSQL標準に従うために別のデータ型になり、VARCHAR2と同義ではなくなる可能性があります。
3.1.4.3.2 空白埋めの動作方法
これは、空白埋めを使用する場合のCHARとVARCHAR2での相違点および考慮事項を説明しています。
次の状況について考えてみます。
-
変数に代入した値がこの変数の最大サイズより短い。
-
列に挿入した値が、定義されている列幅より短い。
-
列から取り出して変数に入れた値が、この変数の最大サイズより短い。
受信者のデータ型がCHARの場合、PL/SQLは最大サイズになるまで値を空白で埋めます。元の値の後続する空白に関する情報は失われます。
受信者のデータ型がVARCHAR2の場合、PL/SQLは値の空白埋めも、後続する空白の削除もしません。文字値はそのまま代入され、情報は失われません。
例3-1 CHARおよびVARCHAR2の空白埋めの相違点
この例では、CHAR変数とVARCHAR2変数は、どちらも最大サイズが10文字です。それぞれの変数に、1つの空白が後続している5文字の値を代入します。CHAR変数に代入した値は空白が埋められて10文字になり、結果の値に含まれる後続の空白6つのうち、1つは元の値に含まれていたものだとは見分けられません。VARCHAR2変数に代入された値は変化しないため、後続の空白が1つあることを確認できます。
DECLARE
first_name CHAR(10 CHAR);
last_name VARCHAR2(10 CHAR);
BEGIN
first_name := 'John ';
last_name := 'Chen ';
DBMS_OUTPUT.PUT_LINE('*' || first_name || '*');
DBMS_OUTPUT.PUT_LINE('*' || last_name || '*');
END;
/
結果:
*John * *Chen *
3.1.4.3.3 値の比較
SQLの文字値の比較ルールが、PL/SQLの文字変数に適用されます。
比較する値の1つまたは両方のデータ型がVARCHAR2またはNVARCHAR2の場合は、非空白埋め比較セマンティクスが適用されますが、それ以外の場合は、空白埋めセマンティクスが適用されます。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
3.1.5 LONGおよびLONG RAW変数
注意:
Oracleは、既存アプリケーションとの下位互換性のためにのみ、LONGおよびLONG RAWデータ型をサポートしています。新しいアプリケーションでは次のようにしてください。
-
LONGのかわりに、VARCHAR2(32760)、BLOB、CLOBまたはNCLOBを使用する。 -
LONGRAWのかわりに、BLOBを使用する。
LONG列には、任意のLONG値を挿入できます。LONG RAW列には、任意のLONG RAW値を挿入できます。LONGまたはLONG RAW列からは、32760バイトを超える長さの値を取り出して、LONGまたはLONG RAW変数に入れることはできません。
LONG列には、任意のCHARまたはVARCHAR2値を挿入できます。LONG列からは、32,767バイトを超える長さの値を取り出してCHAR変数またはVARCHAR2変数に入れることはできません。
LONG RAW列には、任意のRAW値を挿入できます。LONG RAW列からは、32767バイトを超える長さの値を取り出してRAW変数に入れることはできません。
関連項目:
トリガー内のLONGデータ型およびLONG RAWデータ型の制約については、「トリガーのLONGおよびLONG RAWデータ型の制約」を参照してください
3.1.6 ROWIDおよびUROWID変数
ROWIDを取り出してROWID変数に入れる場合は、バイナリ値を文字値に変換するROWIDTOCHARファンクションを使用します。このファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
ROWID変数の値をROWIDに変換するには、CHARTOROWIDファンクション(『Oracle Database SQL言語リファレンス』を参照)を使用します。値が有効なROWIDを表していない場合は、PL/SQLにより事前定義の例外SYS_INVALID_ROWIDが呼び出されます。
ROWIDを取り出してUROWID変数に入れる場合、またはUROWID変数の値をROWIDに変換する場合は、代入文を使用します。変換は暗黙的に実行されます。
注意:
-
UROWIDは論理ROWIDと物理ROWIDの両方と互換性があるため、ROWIDより汎用性の高いデータ型です。 -
ハイブリッド列圧縮(HCC)で圧縮された表の行を更新すると、行の
ROWIDが変更されます。特定のOracleストレージ・システムの機能であるHCCの詳細は、『Oracle Database概要』を参照してください。
3.2 BOOLEANデータ型
PL/SQLのデータ型BOOLEANには、論理値(ブール値のTRUEとFALSE、およびNULL値)が格納されます。NULLは、不明な値を表します。
BOOLEAN変数を宣言するための構文は、次のとおりです。
variable_name BOOLEAN
BOOLEAN変数に代入できる値はBOOLEAN式のみです。詳細は、「ブール式」を参照してください。
SQLにはBOOLEANに相当するデータ型がないため、次の操作は実行できません。
-
データベース表の列に
BOOLEAN値を割り当てる操作 -
データベース表の列の値を選択またはフェッチして
BOOLEAN変数に入れる操作 -
SQLファンクションで
BOOLEAN値を使用する操作(ただし、「例3-3」に示すように、SQL問合せは
BOOLEANパラメータを持つPL/SQLファンクションを起動できます。) -
SQL文(SQL問合せで起動されるPL/SQLファンクションの引数を除く)またはPL/SQL無名ブロックでの
BOOLEAN式の使用注意:
静的SQL問合せで起動されるPL/SQLファンクションの引数は、
BOOLEANリテラルにできません。これを回避するには、「例3-3」に示すように、リテラルを変数に割り当ててからその変数をファンクションに渡します。
BOOLEAN値は、DBMS_OUTPUT.PUTサブプログラムまたはDBMS_OUTPUT.PUTLINEサブプログラムに渡せません。BOOLEAN値を出力するには、IF文またはCASE文を使用して値を文字値に変換します(これらの文の詳細は、「条件付き選択文」を参照してください)。
例3-2 BOOLEAN値の出力
この例では、プロシージャは、BOOLEANパラメータを受け取り、CASE文を使用して、値がNULLならUnknownを、TRUEならYesを、FALSEならNoを出力します。
関連項目:
例2-34を参照してください。この例では、IF文を使用してprint_booleanプロシージャを作成しています。
PROCEDURE print_boolean (b BOOLEAN)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE (
CASE
WHEN b IS NULL THEN 'Unknown'
WHEN b THEN 'Yes'
WHEN NOT b THEN 'No'
END
);
END;
BEGIN
print_boolean(TRUE);
print_boolean(FALSE);
print_boolean(NULL);
END;
結果:
Yes No Unknown
例3-3 SQL文からのBOOLEANパラメータを持つPL/SQLファンクションの起動
この例では、SQL文により、BOOLEANパラメータを持つPL/SQLファンクションが起動されます。
FUNCTION f (x BOOLEAN, y PLS_INTEGER) RETURN employees.employee_id%TYPE AUTHID CURRENT_USER AS BEGIN IF x THEN RETURN y; ELSE RETURN 2*y; END IF; END; DECLARE name employees.last_name%TYPE; b BOOLEAN := TRUE; BEGIN SELECT last_name INTO name FROM employees WHERE employee_id = f(b, 100); DBMS_OUTPUT.PUT_LINE(name); b := FALSE; SELECT last_name INTO name FROM employees WHERE employee_id = f(b, 100); DBMS_OUTPUT.PUT_LINE(name); END; /
結果:
King Whalen
3.3 PLS_INTEGERおよびBINARY_INTEGERデータ型
PL/SQLのデータ型であるPLS_INTEGERとBINARY_INTEGERは同じです。
わかりやすくするために、このマニュアルでは、PLS_INTEGERとBINARY_INTEGERの両方を表すためにPLS_INTEGERを使用します。
PLS_INTEGERデータ型は、32ビットで表される-2147483648から2147483647の範囲の符号付き整数を格納します。
PLS_INTEGERデータ型には、NUMBERデータ型およびNUMBERサブタイプと比べて、次のようなメリットがあります。
-
PLS_INTEGER値の方が、必要な記憶域が少なくなります。 -
PLS_INTEGER演算はハードウェア算術計算を使用するため、ライブラリ算術計算を使用するNUMBER演算より処理速度が速くなります。
効率のために、PLS_INTEGERの範囲内でのすべての計算にPLS_INTEGER値を使用してください。
ここでのトピック
3.3.1 PLS_INTEGERのオーバーフローの回避
PLS_INTEGER範囲をオーバーフローする2つのPLS_INTEGER値を使用した計算では、オーバーフロー例外が発生します。
PLS_INTEGERの範囲外の計算には、NUMBERデータ型の事前定義のサブタイプであるINTEGERを使用します。
例3-4 オーバーフロー例外が発生するPLS_INTEGERの計算
この例では、2つのPLS_INTEGER値を使用する計算がPLS_INTEGERの範囲をオーバーフローした場合は、結果をNUMBERデータ型に代入しても、オーバーフロー例外が発生することを示します。
DECLARE p1 PLS_INTEGER := 2147483647; p2 PLS_INTEGER := 1; n NUMBER; BEGIN n := p1 + p2; END; /
結果:
DECLARE
*
ERROR at line 1:
ORA-01426: numeric overflow
ORA-06512: at line 6例3-5 例3-4のオーバーフローの防止
この例では、PLS_INTEGER範囲外の計算での事前定義のサブタイプINTEGERの正しい使用を示しています。
DECLARE
p1 PLS_INTEGER := 2147483647;
p2 INTEGER := 1;
n NUMBER;
BEGIN
n := p1 + p2;
END;
/
結果:
PL/SQL procedure successfully completed.
3.3.2 PLS_INTEGERの事前定義のサブタイプ
このサマリーは、PLS_INTEGERデータ型の事前定義済のサブタイプ、およびそれらが格納するデータを示します。
表3-3 PLS_INTEGERデータ型の事前定義のサブタイプ
| データ型 | データの説明 |
|---|---|
|
|
負でない |
|
|
|
|
|
正の |
|
|
|
|
|
-1、0または1の |
|
|
|
PLS_INTEGERおよびそのサブタイプは、次のデータ型に暗黙的に変換できます。
-
CHAR -
VARCHAR2 -
NUMBER -
LONG
LONGを除く前述のすべてのデータ型、およびすべてのPLS_INTEGERサブタイプは、PLS_INTEGERに暗黙的に変換できます。
PLS_INTEGER値は、サブタイプの制約に違反していない場合のみ、PLS_INTEGERサブタイプに暗黙的に変換できます。
関連項目:
-
NOTNULL制約の詳細は、「NOT NULL制約」を参照してください -
SIMPLE_INTEGERの詳細は、「PLS_INTEGERのSIMPLE_INTEGERサブタイプ」を参照してください
例3-6 SIMPLE_INTEGERサブタイプの制約違反
この例は、PLS_INTEGER値のNULLをSIMPLE_INTEGERサブタイプにキャストすると例外が発生することを示しています。
DECLARE a SIMPLE_INTEGER := 1; b PLS_INTEGER := NULL; BEGIN a := b; END; /
結果:
DECLARE * ERROR at line 1: ORA-06502: PL/SQL: numeric or value error ORA-06512: at line 5
3.3.3 PLS_INTEGERのSIMPLE_INTEGERサブタイプ
SIMPLE_INTEGERは、PLS_INTEGERデータ型の事前定義済のサブタイプです。
SIMPLE_INTEGERはPLS_INTEGERと同じ範囲を持ち、NOT NULL制約があります。PLS_INTEGERとの大きな違いはオーバーフローの方法です。
変数の値がNULLになることがなく、オーバーフロー・チェックも不要であるとわかっている場合は、PLS_INTEGERではなくSIMPLE_INTEGERとして値を宣言します。SIMPLE_INTEGERの場合は、NULLかどうかのチェックおよびオーバーフロー・チェックのためのオーバーヘッドが発生しないため、PLS_INTEGERよりもパフォーマンスが大幅に向上します。
ここでのトピック
3.3.3.1 SIMPLE_INTEGERのオーバーフローの方法
式に含まれるすべてのオペランドのデータ型がSIMPLE_INTEGERの場合にのみ、PL/SQLで2の補数算術が使用され、オーバーフローが無視されます。
オーバーフローが無視されるため、値を正から負、または負から正にラップできます。次に例を示します。
230 + 230 = 0x40000000 + 0x40000000 = 0x80000000 = -231
-231 + -231 = 0x80000000 + 0x80000000 = 0x00000000 = 0
たとえば、次のブロックはエラーなしで実行されます。
DECLARE
n SIMPLE_INTEGER := 2147483645;
BEGIN
FOR j IN 1..4 LOOP
n := n + 1;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(n, 'S9999999999'));
END LOOP;
FOR j IN 1..4 LOOP
n := n - 1;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(n, 'S9999999999'));
END LOOP;
END;
/
結果:
+2147483646 +2147483647 -2147483648 -2147483647 -2147483648 +2147483647 +2147483646 +2147483645 PL/SQL procedure successfully completed.
3.3.3.2 SIMPLE_INTEGERと他のオペランドの両方を使用する式
SIMPLE_INTEGERと他のオペランドの両方が式に含まれている場合は、PL/SQLによりSIMPLE_INTEGER値がPLS_INTEGER NOT NULLに暗黙的に変換されます。
一部の最適化が抑制されてパフォーマンスに悪影響を与えるような状態でSIMPLE_INTEGER値と他の値が混在している場合は、PL/SQLコンパイラから警告が発行されます。
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