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での最大サイズ

CHAR脚注1

32,767バイト

2,000バイト

NCHAR脚注1

32,767バイト

2,000バイト

RAW脚注1

32,767バイト

2,000バイト脚注2

VARCHAR2脚注1

32,767バイト

4,000バイト脚注2

NVARCHAR2脚注1

32,767バイト

4,000バイト脚注2

LONG脚注3

32,760バイト

2ギガバイト(GB) - 1

LONG RAW脚注3

32,760バイト

2 GB

BLOB

128テラバイト(TB)

(4GB - 1) * database_block_size

CLOB

128 TB

(4GB - 1) * database_block_size

NCLOB

128 TB

(4GB - 1) * database_block_size

脚注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の定数

定数 説明

BINARY_FLOAT_NAN (*)

条件IS NAN(非数値)がTRUEになっているBINARY_FLOAT値。

BINARY_FLOAT_INFINITY (*)

単精度の正の無限大

BINARY_FLOAT_MAX_NORMAL

最大正規BINARY_FLOAT値。

BINARY_FLOAT_MIN_NORMAL

最小正規BINARY_FLOAT値。

BINARY_FLOAT_MAX_SUBNORMAL

最大非正規BINARY_FLOAT値。

BINARY_FLOAT_MIN_SUBNORMAL

最小非正規BINARY_FLOAT値。

BINARY_DOUBLE_NAN (*)

条件IS NAN(非数値)がTRUEになっているBINARY_DOUBLE値。

BINARY_DOUBLE_INFINITY (*)

倍精度の正の無限大

BINARY_DOUBLE_MAX_NORMAL

最大正規BINARY_DOUBLE値。

BINARY_DOUBLE_MIN_NORMAL

最小正規BINARY_DOUBLE値。

BINARY_DOUBLE_MAX_SUBNORMAL

最大非正規BINARY_DOUBLE値。

BINARY_DOUBLE_MIN_SUBNORMAL

最小非正規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など)

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)を使用して、文字数の長さを宣言します(nFLOOR(32767/4) = 8191を超えることはできません)。

関連項目:

Oracle Databaseの文字セットのサポートの詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照してください。

3.1.4.3 CHARとVARCHAR2のデータ型の違い

CHARVARCHAR2のデータ型は、次の点で異なっています。

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)BLOBCLOBまたは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概要』を参照してください。

関連項目:

DBMS_ROWIDパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。このパッケージのサブプログラムを使用すると、ROWID値に関する情報を作成したり戻すことができます(ただし、UROWID値に関してはできません)。