プライマリ・コンテンツに移動
Oracle Database PL/SQL言語リファレンス
12c リリース1 (12.1)
B71296-06
目次へ移動
目次
索引へ移動
索引

前
次

3 PL/SQLのデータ型

PL/SQLの定数、変数、パラメータ、ファンクションの戻り値はすべて、記憶形式および有効な値と演算を決定するデータ型を持っています。

この章では、スカラー・データ型という、内部コンポーネントのない値を格納するデータ型について説明します。

スカラー・データ型にはサブタイプを持たせることができます。サブタイプとは、別のデータ型のサブセットとなるデータ型のことで、その別のデータ型は、そのサブタイプのベース型となります。サブタイプには、そのベース型で有効な演算と同じ演算が含まれています。データ型とそのサブタイプでデータ型ファミリが構成されます。

PL/SQLには、多くの型やサブタイプがパッケージSTANDARDに事前定義されています。また、PL/SQLを使用して、独自のサブタイプを定義することもできます。

PL/SQLのスカラー・データ型は次のとおりです。

ここでのトピック

関連項目:

SQLデータ型

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

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バイト

2GB

BLOB

128テラバイト(TB)

(4GB - 1) * database_block_size

CLOB

128TB

(4GB - 1) * database_block_size

NCLOB

128TB

(4GB - 1) * database_block_size

脚注 1

このデータ型の値の最大サイズをPL/SQLで指定する場合は、定数または変数ではなく、1から32,767の間の値を持つ整数リテラルを使用します。

脚注 2

このサイズの違いをなくすには、『Oracle Database SQL言語リファレンス』の手順に従ってください。

脚注 3

既存のアプリケーションとの下位互換性を保つためにのみサポートされています。

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脚注 4

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

BINARY_FLOAT_INFINITY4

単精度の正の無限大。

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_NAN4

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

BINARY_DOUBLE_INFINITY4

倍精度の正の無限大。

BINARY_DOUBLE_MAX_NORMAL

最大正規BINARY_DOUBLE値。

BINARY_DOUBLE_MIN_NORMAL

最小正規BINARY_DOUBLE値。

BINARY_DOUBLE_MAX_SUBNORMAL

最大非正規BINARY_DOUBLE値。

BINARY_DOUBLE_MIN_SUBNORMAL

最小非正規BINARY_DOUBLE値。

脚注 4

この定数は、SQLでも事前定義されています。

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'を使用する方が、パフォーマンスの向上幅が大きくなります(詳細は、「ハードウェア算術を使用するデータ型の使用」を参照してください)。

CHARおよびVARCHAR2変数

ここでのトピック

長すぎる値の代入または挿入

文字変数に変数の最大サイズより長い値を代入すると、エラーが発生します。次に例を示します。

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

関連項目:

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

CHARとVARCHAR2のデータ型の違い

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

事前定義のサブタイプ

CHARデータ型には、PL/SQLとSQLの両方にCHARACTERというサブタイプが1つ事前定義されています。

VARCHAR2データ型には、PL/SQLとSQLの両方にVARCHARというサブタイプが1つ事前定義されており、PL/SQLには、STRINGというサブタイプがもう1つ事前定義されています。

各サブタイプの値の範囲はそのベース型と同じです。

注意:

PL/SQLの今後のリリースでのVARCHARは、新しいSQL標準に従うために別のデータ型になり、VARCHAR2と同義ではなくなる可能性があります。

空白埋めの動作方法

ここでは、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 *
値の比較

SQLの文字値の比較ルールが、PL/SQLの文字変数に適用されます。

比較する値の1つまたは両方のデータ型がVARCHAR2またはNVARCHAR2の場合は、非空白埋め比較セマンティクスが適用されますが、それ以外の場合は、空白埋めセマンティクスが適用されます。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

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データ型の制約」を参照してください。

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値に関してはできません)。

ブール・データ型

PL/SQLのデータ型BOOLEANには、論理値(ブール値のTRUEFALSE、および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パラメータを受け取り、CASE文を使用して、値がNULLならUnknownを、TRUEならYesを、FALSEならNoを出力します。

関連項目:

例2-35を参照してください。この例では、IF文を使用してprint_booleanプロシージャを作成しています。

例3-3では、SQL文により、BOOLEANパラメータを持つPL/SQLファンクションが起動されます。

例3-2 ブール値の出力

CREATE 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ファンクションの起動

CREATE OR REPLACE 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

PLS_INTEGERおよびBINARY_INTEGERデータ型

PL/SQLのデータ型であるPLS_INTEGERBINARY_INTEGERは同じです。

わかりやすくするために、このマニュアルでは、PLS_INTEGERBINARY_INTEGERの両方を表すためにPLS_INTEGERを使用します。

PLS_INTEGERデータ型は、32ビットで表される-2,147,483,648から2,147,483,647の範囲の符号付き整数を格納します。

PLS_INTEGERデータ型には、NUMBERデータ型およびNUMBERサブタイプと比べて、次のようなメリットがあります。

  • PLS_INTEGER値の方が、必要な記憶域が少なくなります。

  • PLS_INTEGER演算はハードウェア算術計算を使用するため、ライブラリ算術計算を使用するNUMBER演算より処理速度が速くなります。

効率のために、PLS_INTEGERの範囲内でのすべての計算にPLS_INTEGER値を使用してください。

ここでのトピック

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.

PLS_INTEGERの事前定義のサブタイプ

この概要に、PLS_INTEGERデータ型の事前定義のサブタイプ、およびそれらが格納するデータを示します。

表3-3 PLS_INTEGERデータ型の事前定義のサブタイプ

データ型 データの説明

NATURAL

負でないPLS_INTEGER値。

NATURALN

NOT NULL制約が指定された負ではないPLS_INTEGER

POSITIVE

正のPLS_INTEGER値。

POSITIVEN

NOT NULL制約が指定された正のPLS_INTEGER

SIGNTYPE

-1、0または1のPLS_INTEGER値(3値論理のプログラミングに有効です)。

SIMPLE_INTEGER

NOT NULL制約が指定されたPLS_INTEGER値。

PLS_INTEGERおよびそのサブタイプは、次のデータ型に暗黙的に変換できます。

  • CHAR

  • VARCHAR2

  • NUMBER

  • LONG

LONGを除く前述のすべてのデータ型、およびすべてのPLS_INTEGERサブタイプは、PLS_INTEGERに暗黙的に変換できます。

PLS_INTEGER値は、サブタイプの制約に違反していない場合のみ、PLS_INTEGERサブタイプに暗黙的に変換できます。

関連項目:

例3-6 SIMPLE_INTEGERサブタイプの制約違反

次の例は、PLS_INTEGER値のNULLSIMPLE_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

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よりもパフォーマンスが大幅に向上します。

ここでのトピック

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.

SIMPLE_INTEGERと他のオペランドの両方を使用する式

SIMPLE_INTEGERと他のオペランドの両方が式に含まれている場合は、PL/SQLによりSIMPLE_INTEGER値がPLS_INTEGER NOT NULLに暗黙的に変換されます。

一部の最適化が抑制されてパフォーマンスに悪影響を与えるような状態でSIMPLE_INTEGER値と他の値が混在している場合は、PL/SQLコンパイラから警告が発行されます。

SIMPLE_INTEGERの範囲内の整数リテラル

SIMPLE_INTEGERの範囲内の整数リテラルのデータ型はSIMPLE_INTEGERになります。

ただし、算術式内のすべてのオペランドが整数リテラルである場合、PL/SQLでは、下位互換性を確保するために、PLS_INTEGERにキャストされた場合と同様にその整数リテラルが処理されます。

ユーザー定義のPL/SQLサブタイプ

PL/SQLではユーザー独自のサブタイプを定義できます。

ベース型は、CHARDATEまたはRECORDなどのスカラーまたはユーザー定義のPL/SQLデータ型指定子です(事前に定義したユーザー定義のサブタイプが含まれます)。

注意:

このトピック内の情報は、ユーザー定義のサブタイプおよび「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-7 使用意図を示すユーザー定義の無制約のサブタイプ

次の例の無制約のサブタイプであるBalanceCounterは、それぞれのタイプのデータ項目の使用意図を示しています。

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制約のみです。

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

同じデータ型ファミリ内のベース型を使用したサブタイプ

同じデータ型ファミリ内の異なるベース型が2つのサブタイプに使用されている場合は、変換元の値が変換先のサブタイプの制約に違反していない場合のみ、一方から他方へ暗黙的に変換できます。

データ型ファミリでグループ化された事前定義のPL/SQLのデータ型およびサブタイプは、「PL/SQLの事前定義のデータ型」を参照してください。

例3-10 同じファミリ内のベース型を使用するサブタイプ間の暗黙的な変換

次の例では、サブタイプのWordTextに、同じデータ型ファミリ内の異なるベース型が使用されています。最初の代入文では、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