2.6.1 PL/SQLの既知の不具合
Oracle Database18cでのPL/SQLの不具合を次に示します。
2.6.1.1 Oracle Bug#5910872
18cより前のOracle Databaseリリースでは、データをALL
、DBA
、USER_ARGUMENTS
のユーザー・ビューを使用して表示できるように、PL/SQLコンパイラはPL/SQLパッケージ・タイプ引数およびそのすべてのネストされた型のメタデータを収集し、そのデータをディクショナリ表に挿入していました。たとえば、パッケージNestedTypesExample
での次のタイプ宣言を考えてみます。
Type Level2Record is RECORD (Field1 NUMBER); Type Level1Collection is TABLE of
Level2Record index by binary_integer; Type Level0Record is RECORD (Field1
Level1Collection); Procedure NestedTypesProc (Param1 Level0Record);
ALL
、DBA
、USER_ARGUMENTS
ユーザー・ビューが問い合せられると、NestedTypeProc
プロシージャの最上位タイプである、パラメータParam1
、Level0Record
が、Level0Record
内のすべてのネストされた型の拡張説明とともに返されます。
SQL> select argument_name,type_subname,position,sequence,data_level from
user_arguments where object_name='NESTEDTYPESPROC';
ARGUMENT_NAME TYPE_SUBNAME POSITION SEQUENCE DATA_LEVEL
--------------- ----------------- ---------- -------- ----------
PARAM1 LEVEL0RECORD 1 1 0
FIELD1 LEVEL1COLLECTION 1 2 1
LEVEL2RECORD 1 3 2
FIELD1 1 4 3
PL/SQLパッケージ・タイプの説明的なメタデータには、最上位のオブジェクト・タイプのメタデータにアクセスする場合と同じ方法ではアクセスできなかったため、このメタデータが格納されます。トップ・レベルのオブジェクト型およびコレクションでは、ALL_TYPES
および関連するユーザー・ビューALL_TYPE_ATTRS
およびALL_COLL_TYPES
を問い合せてタイプ・メタデータを取得できます。しかし、Oracle Database 12cリリース1 (12.1)より前は、PL/SQLパッケージ・タイプ(レコードやパッケージ化されたコレクションなど)のタイプ・メタデータを取得することはできませんでした。そのため、これらのPL/SQLパッケージ・タイプを参照する関数やプロシージャのパラメータにより、これらのタイプに関するすべてのメタデータをARGUMENTS
ビューに、ネストされたタイプを含めて公開していました。
深くネストされたタイプはSYS
表領域で大量のメモリーを消費する可能性があります。また、ARGUMENTS
ビューでタイプ・メタデータを共有する方法がないため、深くネストされたタイプがある各パラメータにおいて独自にタイプ・メタデータの冗長コピーが必要になります。ARGUMENTS
ビューおよびSYS
表領域のメタデータの量が膨大になると、PL/SQLコンパイラのパフォーマンスの低下を含む様々な問題へとつながりかねません。パフォーマンス低下の原因は、PL/SQLが基礎となるディクショナリ表の行を更新するのに多くの時間を要することです。
回避策:
Oracle Database 12cリリース1 (12.1)では、PL/SQLのパッケージ・タイプのサポートが強化され、これには新しいユーザー・ビューのALL_PLSQL_TYPES
、ALL_PLSQL_TYPE_ATTRS
、ALL_PLSQL_COLL_TYPES
が含まれます。名前が示すように、これらのビューを使用してユーザーはPL/SQLパッケージ・タイプに関するメタデータを問い合せることができます。
Oracle Database 12cリリース1 (12.1)でこのパッケージ・タイプのサポートが追加されたことにより、PL/SQLコンパイラにおいて大量の説明的メタデータをARGUMENTS
ビューに挿入する必要はなくなりました。各パラメータ・タイプのARGUMENTS
ビューにおいて必要なのはタイプ名を含む単一のメタデータ行のみでした。PL/SQLタイプのビューに対する問合せにおいて、タイプ名およびネストされたタイプの完全な詳細を取得できます。
Oracle Databaseリリース18cからはARGUMENTS
ビューに含まれる行の数が減ります。具体的には、最上位レベル(DATA_LEVEL=0
)アイテムのみがARGUMENTS
ビューに格納されます。
たとえば、前述の問合せをOracle Databaseリリース18cで実行すると、返される行の数が次のように減少します(DATA_LEVEL=0
である行のみ)。
ARGUMENT_NAME TYPE_SUBNAME POSITION SEQUENCE DATA_LEVEL
--------------- ----------------- ---------- -------- ----------
PARAM1 LEVEL0RECORD 1 1 0
OCIDescribeAny()
は、ARGUMENTS
ビューで使用されるのと同じメタデータに基づいています。OCIDescribeAny()
も、12cリリース1 (12.1)での変更前にそうであったように複数の行を返すのではなく、各パラメータ・タイプに対して単一行を返します。
ALL
、DBA
およびUSER_ARGUMENTS
ユーザー・ビューにも新しい列タイプTYPE_OBJECT_TYPE
が含まれます。TYPE_OWNER
、TYPE_NAME
およびTYPE_SUBNAME
によって記述されるタイプのタイプを判別するには、TYPE_OBJECT_TYPE
列を使用します。使用可能な値には、TABLE
、VIEW
、PACKAGE
およびTYPE
があります。
引数のメタデータを収集するために以前の動作を必要とする場合は、イベントをevents='10946, level 65536'
に設定します。このイベントを設定するとARGUMENTS
ビューはOracle Database 18cより前のOracle Databaseリリースでの動作に戻り、DATA_LEVEL
を0
より大きくでき、タイプおよびネストされたタイプの説明的メタデータがビューに含まれるようになります。この変更を行う場合は、イベントを設定した後に、影響を受けるパッケージを再コンパイルする必要があります。影響を受けるパッケージの再コンパイル時に、コンパイラにより追加のメタデータが再収集されます。このイベントはまた、OCIDescribeAny()
をOracle Database 18cより前のリリースの動作に戻します。
Oracle Database 12cリリース1 (12.1.0.2)以降では、引数なしでプロシージャを入力するとARGUMENTS
ビューには行は表示されません。これは、ARGUMENTS
ビューの行を減らす変更とは別の追加の変更です。Oracle Database 12cリリース1 (12.1.0.2)より前は、引数なしのプロシージャはARGUMENTS
ビューに単一行として表示されていました。
親トピック: PL/SQLの既知の不具合