3 PL/SQLデータ型
PL/SQLの定数、変数、パラメータ、ファンクションの戻り値はすべて、記憶形式および有効な値と演算を決定するデータ型を持っています。
この章では、スカラー・データ型という、内部コンポーネントのない値を格納するデータ型について説明します。
スカラー・データ型にはサブタイプを持たせることができます。サブタイプとは、別のデータ型のサブセットとなるデータ型のことで、その別のデータ型は、そのサブタイプのベース型となります。サブタイプには、そのベース型で有効な演算と同じ演算が含まれています。データ型とそのサブタイプでデータ型ファミリが構成されます。
PL/SQLには、多くの型やサブタイプがパッケージSTANDARD
に事前定義されています。また、PL/SQLを使用して、独自のサブタイプを定義することもできます。
PL/SQLのスカラー・データ型は次のとおりです。
-
SQLデータ型
-
BOOLEAN
-
PLS_INTEGER
-
BINARY_INTEGER
-
REF
CURSOR
-
ユーザー定義のサブタイプ
ここでのトピック
関連項目:
-
コンポジット・データ型の詳細は、「PL/SQLのコレクションおよびレコード」を参照してください
-
REF
CURSOR
の詳細は、「カーソル変数」を参照してください -
スキーマ・レベルのユーザー定義データ型の作成の詳細は、「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
を使用する。 -
LONG
RAW
のかわりに、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
サブタイプに暗黙的に変換できます。
関連項目:
-
NOT
NULL
制約の詳細は、「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