PL/SQLの定数、変数、パラメータ、ファンクションの戻り値はすべて、記憶形式および有効な値と演算を決定するデータ型を持っています。
この章では、スカラー・データ型という、内部コンポーネントのない値を格納するデータ型について説明します。コンポジット・データ型の詳細は、第5章「PL/SQLのコレクションおよびレコード」を参照してください。
スカラー・データ型にはサブタイプを持たせることができます。サブタイプとは、別のデータ型のサブセットとなるデータ型のことで、その別のデータ型は、そのサブタイプのベース型となります。サブタイプには、そのベース型で有効な演算と同じ演算が含まれています。データ型とそのサブタイプでデータ型ファミリが構成されます。
PL/SQLには、多くの型やサブタイプがパッケージSTANDARD
に事前定義されています。また、PL/SQLを使用して、独自のサブタイプを定義することもできます。
PL/SQLのスカラー・データ型は次のとおりです。
SQLデータ型
BOOLEAN
PLS_INTEGER
BINARY_INTEGER
REF
CURSOR
(「カーソル変数」を参照)
ユーザー定義のサブタイプ
ここでのトピック
関連項目:
|
PL/SQLデータ型にはSQLデータ型が含まれます。SQLデータ型の詳細は、『Oracle Database SQL言語リファレンス』を参照してください(記載されているデータ型およびサブタイプ、データ型の比較のルール、データ変換、リテラル、および書式モデルに関する情報はすべて、次の項目を除き、SQLとPL/SQLの両方に適用されます)。
SQLとは異なり、PL/SQLでは変数を宣言できます。変数には次のトピックが適用されます。
表3-1にリストしたSQLのデータ型は、PL/SQLとSQLで最大サイズが異なります。
表3-1 PL/SQLとSQLで最大サイズが異なるデータ型
データ型 | PL/SQLでの最大サイズ | SQLでの最大サイズ |
---|---|---|
|
32,767バイト |
2000バイト |
|
32,767バイト |
2000バイト |
|
32,767バイト |
2000バイト |
|
32,767バイト |
4000バイト |
|
32,767バイト |
4000バイト |
|
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既存のアプリケーションとの下位互換性のためにのみサポートされています。
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の定数 1
定数 | 説明 |
---|---|
|
条件 |
|
単精度の正の無限大。 |
|
最大正規 |
|
最小正規 |
|
最大非正規 |
|
最小非正規 |
|
条件 |
|
倍精度の正の無限大。 |
|
最大正規 |
|
最小正規 |
|
最大非正規 |
|
最小非正規 |
1 この定数はSQLでも事前定義されています。
PL/SQLでは、次のサブタイプが事前定義されています。
各サブタイプはそのベース型と同じ範囲を取り、NOT
NULL
制約(「NOT NULL制約」を参照)を含んでいます。
値NULL
を取らないとわかっている変数は、BINARY_FLOAT
またはBINARY_DOUBLE
ではなく、SIMPLE_FLOAT
またはSIMPLE_DOUBLE
として宣言します。これらのサブタイプを使用すると、NULLかどうかのチェックのためのオーバーヘッドが発生せず、そのベース型を使用するよりパフォーマンスが大幅に向上します。PLSQL_CODE_TYPE='INTERPRETED'
よりもPLSQL_CODE_TYPE='NATIVE'
を使用する方が、パフォーマンスの向上幅が大きくなります(詳細は、「ハードウェア算術を使用するデータ型の使用」を参照してください)。
文字変数に変数の最大サイズより長い値を代入すると、エラーが発生します。次に例を示します。
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.
CHARまたはVARCHAR2
変数の最大サイズ
は、最大サイズを文字数で指定するかバイト数で指定するかに関係なく、32,767バイトです。変数の最大文字数は、キャラクタ・セットのタイプによって、場合によっては文字自体によって異なります。
キャラクタ・セットのタイプ | 最大文字数 |
---|---|
シングルバイト・キャラクタ・セット | 32,767 |
nバイトの固定幅マルチバイト・キャラクタ・セット(AL16UTF16など) | FLOOR(32,767/ n ) |
文字幅が1とnバイトの間である、nバイトの可変幅マルチバイト・キャラクタ・セット(JA16SJISやAL32UTF8など) | 文字自体によって異なり、32,767(1バイト文字のみを含む文字列の場合)からFLOOR(32,767/ n ) (nバイト文字のみを含む文字列の場合)を指定できます。 |
任意のマルチバイト・キャラクタ・セットで
n
個の文字を常に保持できるように、CHARまたはVARCHAR2変数を宣言する場合は、CHAR(
n
CHAR)
またはVARCHAR2(
n
CHAR)
を使用して、文字数の長さを宣言します(nはFLOOR(32767/4)
= 8191を超えることはできません)。
関連項目: Oracle Databaseのキャラクタ・セットのサポートの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。 |
CHAR
とVARCHAR2
のデータ型は、次の点で異なっています。
CHAR
データ型には、PL/SQLとSQLの両方にCHARACTER
というサブタイプが1つ事前定義されています。
VARCHAR2
データ型には、PL/SQLとSQLの両方にVARCHAR
というサブタイプが1つ事前定義されており、PL/SQLには、STRING
というサブタイプがもう1つ事前定義されています。
各サブタイプの値の範囲はそのベース型と同じです。
注意: PL/SQLの今後のリリースでのVARCHAR は、新しいSQL標準に従うために別のデータ型になり、VARCHAR2 と同義ではなくなる可能性があります。 |
変数に代入した値がこの変数の最大サイズより短い。
列に挿入した値が、定義されている列幅より短い。
列から取り出して変数に入れた値が、この変数の最大サイズより短い。
受信者のデータ型がCHAR
の場合、PL/SQLは最大サイズになるまで値を空白で埋めます。元の値の後続する空白に関する情報は失われます。
受信者のデータ型がVARCHAR2
の場合、PL/SQLは値の空白埋めも、後続する空白の削除もしません。文字値はそのまま代入され、情報は失われません。
例3-1のCHAR
変数とVARCHAR2
変数は、どちらも最大サイズが10文字です。それぞれの変数に、1つの空白が後続している5文字の値を代入します。CHAR
変数に代入した値は空白が埋められて10文字になり、結果の値に含まれる後続の空白6つのうち、1つは元の値に含まれていたものだとは見分けられません。VARCHAR2
変数に代入された値は変化しないため、後続の空白が1つあることを確認できます。
例3-1 CHARおよびVARCHAR2の空白埋めの相違点
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 *
LONG
列には、任意のLONG
値を挿入できます。LONG
RAW
列には、任意のLONG
RAW
値を挿入できます。LONG
またはLONG
RAW
列からは、32760バイトを超える長さの値を取り出して、LONG
またはLONG
RAW
変数に入れることはできません。
LONG
列には、任意のCHAR
またはVARCHAR2
値を挿入できます。LONG
列からは、32767バイトを超える長さの値を取り出してCHAR
変数またはVARCHAR2
変数に入れることはできません。
LONG
RAW
列には、任意のRAW
値を挿入できます。LONG
RAW
列からは、32767バイトを超える長さの値を取り出してRAW
変数に入れることはできません。
ROWIDを取り出してROWID
変数に入れる場合は、バイナリ値を文字値に変換するROWIDTOCHAR
ファンクションを使用します。このファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
ROWID
変数の値をROWIDに変換するには、CHARTOROWID
ファンクション(『Oracle Database SQL言語リファレンス』を参照)を使用します。値が有効なROWIDを表していない場合は、PL/SQLにより事前定義の例外SYS_INVALID_ROWID
が呼び出されます。
ROWIDを取り出してUROWID
変数に入れる場合、またはUROWID
変数の値をROWIDに変換する場合は、代入文を使用します。変換は暗黙的に実行されます。
注意:
|
関連項目: DBMS_ROWIDパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』 を参照してください。このパッケージのサブプログラムを使用すると、ROWID 値に関する情報を作成したり戻すことができます(ただし、UROWID 値に関してはできません)。 |
PL/SQLのデータ型BOOLEAN
には、論理値(ブール値のTRUE
とFALSE
、およびNULL
値)が格納されます。NULL
は、不明な値を表します。
BOOLEAN
変数を宣言するための構文は、次のとおりです。
variable_name BOOLEAN
BOOLEAN
変数に代入できる値はBOOLEAN
式のみです。詳細は、「BOOLEAN式」を参照してください。
SQLにはBOOLEAN
に相当するデータ型がないため、次の操作は実行できません。
データベース表の列にBOOLEAN
値を割り当てる操作
データベース表の列の値を選択またはフェッチしてBOOLEAN
変数に入れる操作
SQL文、SQLファンクションまたはSQL文から起動されたPL/SQLファンクションでBOOLEAN
値を使用する操作
BOOLEAN
値は、DBMS_OUTPUT
.PUT
サブプログラムまたはDBMS_OUTPUT
.PUTLINE
サブプログラムに渡せません。BOOLEAN
値を出力するには、IF
文またはCASE
文を使用して値を文字値に変換します(これらの文の詳細は、「条件付き選択文」を参照してください)。
例3-2のプロシージャは、BOOLEAN
パラメータを受け取り、CASE
文を使用して、値がNULL
ならUnknown
を、TRUE
ならYes
を、FALSE
ならNo
を出力します。
例3-2 BOOLEAN値の出力
CREATE PROCEDURE print_boolean (b BOOLEAN) AUTHID DEFINER 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
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
値を使用してください。
ここでのトピック
2つのPLS_INTEGER
値を使用する計算がPLS_INTEGER
の範囲をオーバーフローした場合は、結果をNUMBER
データ型に代入しても、オーバーフロー例外が発生します(例3-3を参照)。PLS_INTEGER
の範囲外の計算には、NUMBER
データ型の事前定義のサブタイプであるINTEGER
を使用します(例3-4を参照)。
例3-3 オーバーフロー例外が発生するPLS_INTEGERの計算
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-4 例3-3のオーバーフローの回避
DECLARE
p1 PLS_INTEGER := 2147483647;
p2 INTEGER := 1;
n NUMBER;
BEGIN
n := p1 + p2;
END;
/
結果:
PL/SQL procedure successfully completed.
表3-3に、PLS_INTEGERデータ型の事前定義のサブタイプ、およびそれらが格納するデータを示します。
表3-3 PLS_INTEGERデータ型の事前定義のサブタイプ
データ型 | データの説明 |
---|---|
負でない |
|
|
|
正の |
|
|
|
-1、0または1の |
|
|
|
1 NOT
NULL
制約の詳細は、「NOT NULL制約」を参照してください。
PLS_INTEGER
およびそのサブタイプは、次のデータ型に暗黙的に変換できます。
CHAR
VARCHAR2
NUMBER
LONG
LONG
を除く前述のすべてのデータ型、およびすべてのPLS_INTEGER
サブタイプは、PLS_INTEGER
に暗黙的に変換できます。
PLS_INTEGER
値は、サブタイプの制約に違反していない場合のみ、PLS_INTEGER
サブタイプに暗黙的に変換できます。たとえば、PLS_INTEGER
値のNULL
をSIMPLE_INTEGER
サブタイプにキャストすると例外が発生します(例3-5を参照)。
SIMPLE_INTEGER
は、PLS_INTEGER
データ型の事前定義されたサブタイプであり、PLS_INTEGER
と同じ範囲を取り、NOT
NULL
制約を含んでいます(「NOT NULL制約」を参照)。PLS_INTEGER
との大きな違いはオーバーフローの方法です。
変数の値がNULL
になることがなく、オーバーフロー・チェックも不要であるとわかっている場合は、PLS_INTEGER
ではなくSIMPLE_INTEGER
として値を宣言します。SIMPLE_INTEGER
の場合は、NULLかどうかのチェックおよびオーバーフロー・チェックのためのオーバーヘッドが発生しないため、PLS_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.
SIMPLE_INTEGER
と他のオペランドの両方が式に含まれている場合は、PL/SQLによりSIMPLE_INTEGER
値がPLS_INTEGER
NOT
NULL
に暗黙的に変換されます。
一部の最適化が抑制されてパフォーマンスに悪影響を与えるような状態でSIMPLE_INTEGER
値と他の値が混在している場合は、PL/SQLコンパイラから警告が発行されます。
SIMPLE_INTEGER
の範囲内の整数リテラルのデータ型はSIMPLE_INTEGER
になります。ただし、算術式内のすべてのオペランドが整数リテラルである場合、PL/SQLでは、下位互換性を確保するために、PLS_INTEGER
にキャストされた場合と同様にその整数リテラルが処理されます。
PL/SQLではユーザー独自のサブタイプを定義できます。ベース型は、CHAR
、DATE
またはRECORD
などのスカラーまたはユーザー定義のPL/SQLデータ型指定子です(事前に定義したユーザー定義のサブタイプが含まれます)。
サブタイプの役割は次のとおりです。
ANSI/ISOデータ型との互換性の提供
その型のデータ項目の使用意図の提示
範囲外の値の検出
ここでのトピック
無制約のサブタイプには、そのベース型と同じ値セットが含まれているため、ベース型の別名にすぎません。したがって、同じベース型の無制約のサブタイプは互換性があり、そのベース型との互換性もあります。データ型の変換は発生しません。
無制約のサブタイプを定義するには、次の構文を使用します。
SUBTYPE subtype_name IS base_type
subtype_name
およびbase_type
の詳細は、「subtype_definition」を参照してください。
無制約のサブタイプの例を示します。これは、ANSIとの互換性のためにPL/SQLで事前定義されているものです。
SUBTYPE "DOUBLE PRECISION" IS FLOAT
例3-6の無制約のサブタイプであるBalance
とCounter
は、それぞれのタイプのデータ項目の使用意図を示しています。
例3-6 使用意図を示すユーザー定義の無制約のサブタイプ
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; /
制約付きサブタイプには、そのベース型の値のサブセットのみが含まれています。
サイズ、精度と位取り、または値の範囲を指定できるベース型の場合は、そのサブタイプにもこれらを指定できます。次に、サブタイプを定義する構文を示します。
SUBTYPE subtype_name IS base_type { precision [, scale ] | RANGE low_value .. high_value } [ NOT NULL ]
この構文を使用しない場合、サブタイプに指定されるのはNOT
NULL
制約(「NOT NULL制約」を参照)のみです。
SUBTYPE subtype_name IS base_type [ NOT NULL ]
注意: 値の範囲を指定できるベース型は、PLS_INTEGER とそのサブタイム(事前定義とユーザー定義の両方)のみです。 |
例3-7では、制約付きサブタイプBalance
を使用して範囲外の値を検出します。
例3-7 範囲外の値を検出するユーザー定義の制約付きサブタイプ
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-5を参照)。
制約付きサブタイプは、変換元の値が変換先のサブタイプの制約に違反していない場合のみ、同じベース型を使用する別の制約付きサブタイプに暗黙的に変換できます。
例3-8では、3つの制約付きサブタイプに同じベース型が使用されています。最初の2つのサブタイプは、3番目のサブタイプに暗黙的に変換できますが、相互には変換できません。
例3-8 同じベース型を使用する制約付きサブタイプ間の暗黙的な変換
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
同じデータ型ファミリ内の異なるベース型が2つのサブタイプに使用されている場合は、変換元の値が変換先のサブタイプの制約に違反していない場合のみ、一方から他方へ暗黙的に変換できます。(データ型ファミリでグループ化された事前定義のPL/SQLのデータ型およびサブタイプは、付録E「PL/SQLの事前定義のデータ型」を参照してください。)
例3-9では、サブタイプのWord
とText
に、同じデータ型ファミリ内の異なるベース型が使用されています。最初の代入文では、Word
の値が暗黙的にText
に変換されます。2番目の代入文では、Text
の値が暗黙的にWord
に変換されます。3番目の代入文では、Text
の値が長すぎるため、値を暗黙的にWord
に変換することができません。
例3-9 同じファミリ内のベース型を使用するサブタイプ間の暗黙的な変換
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; -- 5-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