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コンパイラから警告が発行されます。