このマニュアルの他の章では、Oracleオブジェクトで作業を開始するために必要なトピックについて説明しています。この章では、オブジェクト・リレーショナル技法を大規模なアプリケーションまたは複雑なスキーマに適用する場合について説明します。
内容は次のとおりです。
オブジェクト型の複合構造を、単純な構造の表に自動的にマップします。
この項の内容は次のとおりです。
オブジェクト型はツリー構造に似ており、ブランチが属性を表します。それ自体がオブジェクトである属性は、それ自体の属性に対してサブブランチを発生させます。
最終的に、各ブランチの終わりは、組込み型(NUMBER
、VARCHAR2
、REF
など)またはコレクション型(VARRAY
、ネストした表など)の属性になります。元のオブジェクト型のこのようなリーフ・レベル属性は、それぞれ表の列に格納されます。
コレクション型ではないリーフ・レベル属性は、オブジェクト型のリーフ・レベル・スカラー属性と呼ばれます。
オブジェクト表では、すべてのリーフ・レベル・スカラー属性またはREF
属性に対するデータが、個々の列に格納されます。各VARRAY
も、大きすぎないかぎり、列に格納されます。ネストした表型のリーフ・レベル属性は、オブジェクト表に対応付けられた個々の表に格納されます。これらの表は、オブジェクト表宣言の一部として宣言する必要があります。「VARRAYの内部レイアウト」および「ネストした表の内部レイアウト」を参照してください。
オブジェクト表にあるオブジェクトの属性を取り出したり、変更する場合、対応する操作が表の列で実行されます。オブジェクト自体の値にアクセスすると、オブジェクト表の列を引数として使用し、その型のデフォルトのコンストラクタを起動することによって、オブジェクトのコピーが生成されます。
システムによって生成されたオブジェクト識別子は、非表示列に格納されます。オブジェクト識別子を使用して、そのオブジェクトに対するREF
を作成します。
表がオブジェクト型の列とともに定義されている場合、オブジェクト型のリーフ・レベル属性に対する表に、非表示列が追加されます。オブジェクト型の各列には、その列オブジェクトのNULL情報(トップレベルのオブジェクトおよびネストしたオブジェクトのアトミックNULL)を格納するための非表示列があります。
代入可能な列またはオブジェクト表には、その列オブジェクトの各属性に対してのみでなく、そのオブジェクト型のサブタイプに追加された各属性に対しても、非表示列があります。これらの列には、代入可能な列に挿入されたサブタイプのインスタンスに対する属性の値が格納されます。
たとえば、person_typ
の代入可能な列には、person_typ
の各属性、具体的にはidno
、name
およびphone
に対する非表示列が対応付けられます。また、person_typ
のサブタイプの属性の非表示列も作成されます。たとえば、student_typ
に対するdept_id
とmajor
、およびpart_time_student_typ
に対するnumber_hours
が作成されます。
サブタイプが作成されると、そのサブタイプに追加された属性の非表示列が、その新しいサブタイプの祖先クラスの代入可能な列を含む表に自動的に追加されます。追加された非表示列は、表にレトロフィットして、新しい型のデータを格納できるようになります。なんらかの理由で、非表示列を追加できない場合は、そのサブタイプの作成はロールバックされます。
サブタイプがDROP TYPE
に対するVALIDATE
オプションを使用して削除された場合は、各サブタイプの固有の属性に対するこのような非表示列はすべて、自動的に削除されます。
代入可能な列には、非表示の型判別式の列が対応付けられます。この列には、型IDと呼ばれる識別子があり、この識別子によって、代入可能な列中の各オブジェクトのうち、最も具体的な型が識別されます。通常、型ID(RAW
)は1バイトですが、大きな階層の場合は最大4バイトまでとなります。
指定されたオブジェクト・インスタンスの型IDは、ファンクションSYS_TYPEID
を使用して特定できます。たとえば、代入可能なオブジェクト表person_obj_table
に、例2-20に示す3つの行があるとします。
例8-1の問合せによって、この表に格納されているオブジェクト・インスタンスの型IDが取得されます。
NAME TYPEID
------------------------------ ---------------------------
Bob Jones 01
Joe Lane 02
Kim Patel 03
カタログ・ビューのUSER_TYPES
、DBA_TYPES
およびALL_TYPES
には、各型に対する型ID値を与えるTYPEID
列(非表示ではない)があります。この列に対して結合を実行して、型判別式の列にある型IDに対応する型名を取得できます。SYS_TYPEID
および型IDの詳細は、「SYS_TYPEID」を参照してください。
行オブジェクトに対して作成されるREF
は、オブジェクト識別子(OID)、オブジェクト表のいくつかのメタデータ、およびROWID
(オプション)で構成されます。
REF
型の列にあるREF
のサイズは、その列に対応付けられた記憶域プロパティに依存します。たとえば、列がREF
WITH
ROWID
として宣言されている場合、ROWID
はREF
列に格納されます。ROWID
のヒントは、制約付きREF
列にあるオブジェクト参照では無視されます。
列がSCOPE
句を使用してREF
として(有効範囲付きREF
として)宣言されている場合、オブジェクト表のメタデータおよびROWID
は省略されて、その列は小さくなります。有効範囲付きREF
の長さは、16バイトです。
OIDが主キー・ベースの場合、主キーを導出する列の数に基づいて、主キーの値を格納するための1つ以上の内部列が作成されます。
ネストした表の行は、別の記憶表に格納されます。ネストした表には、行ごとに1つの記憶表ではなく、列ごとに1つの記憶表が対応付けられています。記憶表は、その列にあるすべてのネストした表に対するすべての要素を保持しています。記憶表には、システム生成の値を持つ非表示のNESTED_TABLE_ID
列があります。この値によって、ネストした表の要素が適切な行にマップされます。
記憶表を索引構成表(IOT)にすることによって、コレクション全体を取り出す問合せを高速化できます。ORGANIZATION INDEX
句をSTORE AS
句の中に挿入します。
ネストした表型は、オブジェクトまたはスカラーを含むことができます。
要素がオブジェクトである場合、記憶表はオブジェクト表のようになります。つまり、そのオブジェクト型のトップレベルの属性が記憶表の列となります。ただし、ネストした表の行にはOIDの列がないため、ネストした表のオブジェクトに対するREF
の作成はできません。
要素がスカラーである場合、記憶表には、スカラー値を含むCOLUMN_VALUE
という単一の列が含まれます。
「ネストした表の記憶域」を参照してください。
VARRAY
のすべての要素は、単一の列に格納されます。配列のサイズに基づいて、VARRAYはインラインまたはBLOB
に格納されます。詳細は、「VARRAYの記憶域上の考慮点」を参照してください。
この項では、型IDおよび属性での索引の使用方法を説明します。
この項の内容は次のとおりです。
SYS_TYPEID
ファンクションを使用して、代入可能な各列にある非表示の型判別式の列に索引を作成できます。型判別式の列には、型IDがあり、この識別子によって、代入可能な列中の各オブジェクト・インスタンスのうち、最も具体的な型が識別されます。この情報は、型に基づいてフィルタにかけるIS OF
述語を使用する問合せの評価に使用されるものですが、SYS_TYPEID
ファンクションを使用して独自の目的で型IDにアクセスすることも可能です。
一般に、型判別式の列には、わずかな数の型IDのみが格納されています。関連のある型階層に含まれている型の数を超えることはありません。この列はカーディナリティが低いので、ビットマップ索引の作成に適しています。
たとえば、次の文では、表contacts
の代入可能なcontact
列の基礎となる型判別式の列のビットマップ索引を作成します。SYS_TYPEID
ファンクションを使用して、型判別式の列が参照されます。
CREATE BITMAP INDEX typeid_idx ON contacts (SYS_TYPEID(contact));
代入可能な列内に格納できる任意の型の属性に対して索引を作成できます。サブタイプの属性は、TREAT
ファンクションを使用して求めるサブタイプ(およびそのサブタイプ)以外の型をフィルタにかけて排除することによってCREATE INDEX
文で参照できます。その後、ドット表記によって、希望の属性を指定します。
たとえば、次の文では、contacts
表にある、すべての学生のmajor
属性に対する索引が作成されます。contact
列の宣言された型はperson_typ
で、student_typ
がそのサブタイプです。したがって、この列にはperson_typ
、student_typ
のインスタンスおよびいずれかのサブタイプが格納されます。
CREATE INDEX major1_idx ON contacts (TREAT(contact AS student_typ).major);
student_typ
は、最初にmajor
属性を定義した型です。person_typ
スーパータイプにはこの型はありません。したがって、major
属性に対する非表示列のすべての値は、student_typ
またはparttimestudent_typ
の著者(student_typ
サブタイプ)に対する値です。つまり、非表示列の値は、TREAT
式によって戻される値と同一であることを意味しています。この式は、学生のサブタイプも含めて、すべての学生のmajor
の値を戻します。つまり、非表示列も、TREAT
式もともに、学生については専攻を、他の型の著者についてはNULLをリストします。このことを利用して、非表示列に対する索引major1_idx
が、通常のBツリー索引として作成されます。
非表示列の値は、前述のように、TREAT
式によって戻される値と同一です。ただし、TREAT
ファンクションのターゲットとして指定された型(前述の例では、student_typ
)が最初にその属性を定義した型である場合にかぎります。TREAT
ファンクションのターゲットが、次の例のように、単にその属性を継承するサブタイプである場合は、TREAT
式は、サブタイプ(定時制の学生)に対してはNULL以外のmajor
値を戻しますが、スーパータイプ(その他の学生)に対しては非NULLは戻しません。
CREATE INDEX major2_idx ON contacts (TREAT(contact AS part_time_student_typ).major);
この場合、非表示列にmajor
の値として格納されている値は、TREAT
式の結果とは異なっている場合があります。したがって、通常のBツリー索引を基礎となる列に対して作成することはできません。このような場合、Oracleでは、TREAT
式は他のすべてのファンクション・ベースの式と同様に処理され、索引を、結果に対するファンクション索引として作成する試みが行われます。
次の例では、前述の例と同様に、定時制の学生のmajor
属性に対してファンクション索引を作成しますが、この例では、major
の非表示列は、代入可能なオブジェクト表person_obj_table
に対応付けられています。
CREATE INDEX major3_idx ON person_obj_table p (TREAT(VALUE(p) AS part_time_student_typ).major);
オブジェクト型の変更を、型進化といいます。オブジェクト型は、次の方法で変更できます。
属性またはメソッドの追加および削除
長さ、精度または位取りを引き上げるための数値属性の修正
文字長を長くするための可変長文字属性の修正
型のFINAL
およびINSTANTIABLE
プロパティの変更
VARRAY
の制限およびサイズの変更
コレクション要素の長さ、精度およびスケールの変更
型を変更すると、その型を参照する項目にも影響します。たとえば、新しい属性を型に追加する場合、その新しい属性を追加できるように、その型の列にあるデータを提示する必要があります。
型を直接的または間接的に参照するスキーマ・オブジェクトで、その型に加えられた変更に影響されるものを、その型の依存オブジェクトといいます。型は、次の依存オブジェクトを持つことができます。
表
型またはサブタイプ
プログラム・ユニット(PL/SQLブロック): プロシージャ、ファンクション、パッケージ、トリガー
索引タイプ
ビュー(オブジェクト・ビューも含む)
ファンクション索引
演算子
依存スキーマ・オブジェクトが型の変更によってどのような影響を受けるかは、オブジェクトによって、また、型に加えられた変更の性質によって異なります。
すべての依存プログラム・ユニット、ビュー、演算子および索引タイプは、型が変更されると、無効としてマークされます。これらの無効となったスキーマ・オブジェクトのいずれかが次回参照されると、新しい型の定義を使用して再検証されます。オブジェクトの再コンパイルが成功すると、そのオブジェクトは有効となり、再度使用できるようになります。型に加えられた変更によっては、ファンクション索引が削除または無効化され、再構築が必要です。
型に依存表がある場合は、型に加えられた各属性に対して、新しい属性の型に依存する表に1つ以上の内部列が追加されます。新しい属性が追加される際は、NULL
値が設定されます。削除された各属性に対応付けられている列は削除されます。変更された各属性に対応付けられた長さ、精度またはスケールも、変更内容に対応して変更されます。
これらの変更には、主に表のメタデータ(表の構造に関する情報で、その列および列の型を記述するデータ)の更新がかかわっているので、迅速な処理が必要です。さらに、このような表データは、型の新しいバージョンの形式に合せた更新も必要です。このデータの更新は、データの量によっては時間がかかる場合があるため、ALTER TYPE
コマンドにオプションが用意されています。このオプションによって、すべての依存表データを即時変換するか、元の形式のままにしておいて、更新のたびに少しずつ変換するかを選択できます。
ALTER TYPE
のCASCADE
オプションは、型の変更を依存型および依存表に伝播します。「型進化に使用するALTER TYPE文」を参照してください。CASCADE
自体に、伝播の一環として表データを新しい型形式に変換するかどうかを選択できるオプションがあります。INCLUDING TABLE DATA
オプションはデータを変換し、NOT INCLUDING TABLE DATA
オプションはデータを変換しません。デフォルトでは、CASCADE
オプションはデータを変換します。いずれの場合も、表データは常に最新バージョンの型の形式で戻されます。表データが以前の型バージョンの形式で保存されている場合は、データが実際に保存されている形式はデータが再書込みされないかぎり変更されないにしても、そのデータは、戻される前に最新バージョンの形式に変換されます。
最新の型の定義は、システム・ビューUSER_SOURCE
から取り出せます。USER_TYPE_VERSIONS
ビューで、ある型のすべてのバージョンの定義を参照できます。
関連項目 型の定義および型本体のコンパイルの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。 |
型に対する構造的な変更のみが依存データに影響し、データの変換を必要とします。ある型のメソッドの定義や動作(型のメソッドが実装されている場合の型本体の動作)に限定された変更は影響しません。
型に対する次の変更は構造的変更です。
属性の追加
属性の削除
属性の長さ、精度、スケールの変更
型のファイナリティ(サブタイプを導出できるかどうかを決定する)のFINAL
からNOT FINAL
への変更、またはNOT FINAL
からFINAL
への変更
このような変更の結果、変更された型およびそのすべての依存型のバージョンが新しいバージョンになり、新しいバージョンへの変更のプロセスの一環として、依存表の内部列が追加、削除または変更されます。
これらのいずれかの変更を、依存型または依存表を持つ型に対して実行すると、変更を伝播した影響は、メタデータのみでなく、データ記憶域の構成にも影響し、データの変換を必要とします。
データの変換以外にも、変更すべき項目がある場合があります。たとえば、新しい属性が型に追加されて、その型が、その型のコンストラクタをコールする場合、型本体の各コンストラクタは、新しい属性に対する値を指定するように修正する必要があります。同様に、新しいメソッドが追加される場合は、型本体を置換して、新しいメソッドの実装を追加する必要があります。型本体は、CREATE OR REPLACE TYPE BODY
文を使用して変更できます。
例8-2に、ある属性を追加し、別の属性を削除することによってperson_typ
に単純な変更を加える方法を示します。CASCADE
キーワードは、型の変更を依存型および依存表に伝播しますが、NOT
INCLUDING
TABLE
DATA
句によって関連するデータの変換が阻止されています。
例8-2 属性の追加および削除によるオブジェクト型の変更
CREATE TYPE person_typ AS OBJECT ( idno NUMBER, name VARCHAR2(30), phone VARCHAR2(20)); / CREATE TABLE person_obj_table OF person_typ; INSERT INTO person_obj_table VALUES (person_typ(12, 'Bob Jones', '650-555-0130')); SELECT value(p) FROM person_obj_table p;
VALUE(P)(IDNO, NAME, PHONE)
--------------------------------------------
PERSON_TYP(12, 'Bob Jones', '650-555-0130')
-- add the email attribute and drop the phone attribute ALTER TYPE person_typ ADD ATTRIBUTE (email VARCHAR2(80)), DROP ATTRIBUTE phone CASCADE NOT INCLUDING TABLE DATA; -- Disconnect and reconnect to accommodate the type change -- The data of table person_obj_table has not been converted yet, but -- when the data is retrieved, Oracle returns the data based on -- the latest type version. The new attribute is initialized to NULL. SELECT value(p) FROM person_obj_table p;
VALUE(P)(IDNO, NAME, EMAIL)
---------------------------------
PERSON_TYP(12, 'Bob Jones', NULL)
SELECT
文では、列データが最新の型バージョンに変換されている可能性があるとしても、変換されたデータが列に再度書き込まれることはありません。ある表の特定のユーザー定義型の列が頻繁に取り出される場合、データ変換が重複して行われないようにするため、そのデータを最新の型バージョンに変換することを検討してください。変換は、列にVARRAY
属性が含まれている場合、特に大きな効果があります。通常、VARRAY
の方がオブジェクトやネストした表列より変換に必要な時間が長くなります。
データの列は、UPDATE
文を発行して、その列を自らに設定することによって変換できます。次に例を示します。
UPDATE dept_tab SET emp_array_col = emp_array_col;
ある表内のすべての列を、UPGRADE
INCLUDING
DATA
とともにALTER
TABLE
を使用して変換できます。次に例を示します。
ALTER TYPE person_typ ADD ATTRIBUTE (photo BLOB) CASCADE NOT INCLUDING TABLE DATA; ALTER TABLE person_obj_table UPGRADE INCLUDING DATA;
ALTER
TABLE
行は、リストされた表のみを変換します。CASCADE
オプションは、他の表または依存オブジェクトが変換されないようにします。
この項では、型に複雑な変更を加える手順を説明します。この種の変更では、ネストした表に含まれているオブジェクト型に、ネストした表属性を追加する必要があります。影響を受けるネストした表をアップグレードするときに、新規の記憶表の名前を指定します。
次の、person_typ
オブジェクト型に基づくスキーマについて考えてみます。
CREATE TYPE people_typ AS TABLE OF person_typ;/ CREATE TYPE department_typ AS OBJECT ( manager person_typ, employee people_typ);/ CREATE TABLE department OF department_typ NESTED TABLE employee STORE AS employee_store_nt;
この型を変更するため、ALTER TYPE
文を発行します。
ALTER TYPE
文にオプションが指定されていない場合、デフォルトの動作では、ターゲットの型に依存するオブジェクトが存在しないかを調べます。なんらかの依存オブジェクトが存在する場合は、この文は異常終了します。オプションのキーワードによって、型の変更を依存型および依存表に連鎖的に波及させることができます。
例8-3のALTER
TYPE
文では、時間を節約するために型および表のチェックをすべて迂回して、依存オブジェクトを無効としています。表のデータには、有効化されるまでアクセスできません。
例8-3 ネストした表属性の追加によるオブジェクト型の変更
-- Create and add a new nested table attribute to person_typ CREATE TYPE tasks_typ AS OBJECT ( priority VARCHAR2(2), description VARCHAR2(30)); / CREATE TYPE tasks_nttab AS TABLE OF tasks_typ; / ALTER TYPE person_typ ADD ATTRIBUTE tasks tasks_nttab INVALIDATE; -- Propagate the change to employee_store_nt -- Specify a storage name for the new nested table ALTER TABLE employee_store_nt UPGRADE NESTED TABLE tasks STORE AS tasks_nt;
必要な場合は、CREATE OR REPLACE TYPE BODY
を使用して、対応する型本体を更新して、新しい型定義に更新します。
依存表を最新の型バージョンにアップグレードし、表データを変換します。
必要に応じて、PL/SQL依存プログラム・ユニットを変更して、型に加えられた変更に対応します。
アプリケーションがC言語で書かれているか、Javaで書かれているかによって、OTTまたはJPublisher(または別のツール)を使用して、新しいヘッダー・ファイルを生成します。
スーパータイプに新しい属性を追加すると、サブタイプの属性が新しい属性を継承するために、そのすべてのサブタイプの属性数が増大する可能性があります。継承された属性は、常に、宣言された(ローカルに定義された)属性に先行するので、新しい属性をスーパータイプに追加すると、各サブタイプのすべての宣言された属性の順序が1つずつ再帰的に増加されます。変更された型のマッピングを更新して、新しい属性を追加する必要があります。OTTとJPublisherがこのタスクを実行します。他のツールを使用する場合は、型のヘッダーが、サーバーでの型の定義と適切に同期されることを確認する必要があります。この同期が確実に行われない場合は、結果として予期しない動作が発生する可能性があります。
必要に応じてアプリケーション・コードを修正し、アプリケーションを再作成します。
ALTER TYPE
文の実行の際に、最初に、要求された型の変更について、構文上およびセマンティクス上の妥当性がチェックされます。CREATE TYPE
文についても同様の妥当性チェックおよび追加の妥当性チェックが実行されます。たとえば、削除の対象となっている属性が、パーティション化キーで使用されていないかが確認されます。ターゲットの型の新しい仕様またはその依存型のいずれかについて型の妥当性が確認されない場合は、ALTER TYPE
文は異常終了します。この場合は、新しい型バージョンは作成されず、すべての依存オブジェクトが変更されないままになります。
依存表が存在する場合は、さらにチェックが行われて、表および索引に関連する制約が遵守されているかが確認されます。ここでも、ALTER TYPE
文について、表に関連する制約のチェックが失敗すると、型の変更は異常終了し、その型の新しいバージョンは作成されません。
複数の属性が単一のALTER TYPE
文に追加される場合は、指定された順序で追加されます。1つのALTER TYPE
文で複数の型の変更を指定することはできますが、属性名およびメソッド・シグネチャは1回のみの指定となります。たとえば、単一の文で同じ属性の追加と変更を行うことはできません。
次に例を示します。
CREATE TYPE mytype AS OBJECT (attr1 NUMBER, attr2 NUMBER); / ALTER TYPE mytype ADD ATTRIBUTE (attr3 NUMBER), DROP ATTRIBUTE attr2, ADD ATTRIBUTE attr4 NUMBER CASCADE;
この結果、mytypeの定義は次のようになります。
(attr1 NUMBER, attr3 NUMBER, attr4 NUMBER);
次のALTER TYPE
文は、同じ属性(attr5
)に対して複数の変更を加えようとするもので、これは無効です。
-- invalid ALTER TYPE statement ALTER TYPE mytype ADD ATTRIBUTE (attr5 NUMBER, attr6 CHAR(10)), DROP ATTRIBUTE attr5;
次に、妥当性チェックに対する制約、表の制限、および型に対して可能な様々な種類の変更についてのその他の情報に関する注意事項を示します。
属性の削除
ルート型に由来するすべての属性を削除することはできません。属性ではなく型を削除する必要があります。サブタイプのすべての属性はスーパータイプから継承されるため、サブタイプからすべての属性を削除しても、その属性のカウントは0(ゼロ)にはなりません。サブタイプでローカルに宣言された属性を削除することは許可されます。
ターゲットの型でローカルに宣言された型のみを削除できます。継承された属性を、サブタイプから削除することはできません。属性がローカルに宣言された場所でその型からその属性を削除してください。
表パーティションの一部である属性または表のサブパーティション・キーの削除はできません。
オブジェクト表またはIOTの主キーOIDの属性の削除はできません。
属性が削除されると、削除された属性に対応する列は削除されます。
索引、統計、制約、および削除された属性を参照する参照整合性制約は削除されます。
長さ、精度またはスケールを増大するための属性の型の変更
メソッドの削除
メソッドは、そのメソッドの定義(または再定義)が行われた型からのみ削除できます。継承されたメソッドをサブタイプから削除することはできません。また、再定義したメソッドをスーパータイプから削除することもできません。
メソッドが再定義されていない場合、CASCADE
オプションを使用してそのメソッドを削除すると、ターゲットの型に由来するメソッドおよびすべてのサブタイプが削除されます。一方、メソッドがサブタイプで再定義されている場合は、CASCADE
は実行されないで、ロールバックされます。CASCADE
が実行されるためには、メソッドを定義しているサブタイプから再定義されたメソッドを削除して、その後、スーパータイプからメソッドを削除します。
USER_DEPENDENCIES
表に、型も含めて、与えられた型に依存するすべてのスキーマ・オブジェクトがあります。また、DBMS_UTILITY.GET_DEPENDENCY
ユーティリティを実行して、型の依存関係を検索できます。
INVALIDATE
オプションを使用して、再定義されたメソッドを削除できますが、サブタイプの再定義されたバージョンは、依然として手動で削除する必要があります。サブタイプは、再定義されたバージョンを削除するように明示的に変更されないかぎり、無効な状態のままです。それまでは、妥当性チェックのためにサブタイプを再コンパイルしようとすると、「メソッドは上書きしません。」
というエラーが発生します。
CASCADE
とは異なり、INVALIDATE
は、型および表のすべてのチェックを迂回して、その型に依存するすべてのスキーマ・オブジェクトを無効とします。それらのオブジェクトは、次回のアクセス時に再検証されます。このオプションは、CASCADE
を使用するより高速に処理されますが、依存型および依存表の再検証時に問題が発生しないことが確認されている必要があります。表が無効な場合は、表データにはアクセスできません。表の妥当性が検証できない場合は、そのデータはアクセス不可のままとなります。
「型の変更の妥当性チェックに失敗した場合」を参照してください。
FINALプロパティまたはINSTANTIABLEプロパティの修正
その型に表依存オブジェクトがない場合にかぎり、オブジェクト型をINSTANTIABLE
からNOT INSTANTIABLE
へ変更できます。
オブジェクト型のNOT INSTANTIABLE
からINSTANTIABLE
への変更は任意の時点で実行できます。このように変更した場合、表には影響しません。
オブジェクト型をFINAL
からNOT FINAL
、またはその逆に変更する場合は、CASCADE
を使用して依存列内および依存表内のデータを即時変換する必要があります。CASCADE
オプションNOT INCLUDING TABLE DATA
を使用して、データを遅延させることはできません。
型をNOT FINAL
からFINAL
に変換する場合は、CASCADE INCLUDING TABLE DATA
を使用する必要があります。型をFINAL
からNOT FINAL
に変更する場合は、CASCADE INCLUDING TABLE DATA
またはCASCADE CONVERT TO SUBSTITUTABLE
のいずれかを使用できます。
型をFINAL
からNOT
FINAL
に変更する場合、既存の列および表で変更する型の新しいサブタイプを挿入可能にするかどうかによって、選択するCASCADE
オプションが異なります。
デフォルトでは、型をFINAL
からNOT
FINAL
に変更することで、代入可能な新しい表およびその型の列を作成できますが、その型の既存の列(またはオブジェクト表)が自動的に代入可能になることはありません。実際、その逆の動作が行われます。その型の既存の列および表はNOT SUBSTITUTABLE
AT
ALL
LEVELS
とマークされます。そのような列の埋込み属性が代入可能な場合は、エラーが生成されます。変更された型の新しいサブタイプは、そのような既存の列および表には挿入できません。
既存の型の列および表を代入可能にするようオブジェクト型をNOT
FINAL
に変更する場合(NOT
SUBSTITUTABLE
とマークされていないことを前提)は、CASCADE
オプションCONVERT TO SUBSTITUTABLE
を使用します。次に例を示します。
例8-5 FINALからNOT FINALへの型の変換
CREATE TYPE shape AS OBJECT ( name VARCHAR2(30), area NUMBER) FINAL;/ ALTER TYPE shape NOT FINAL CASCADE CONVERT TO SUBSTITUTABLE;
このCASCADE
オプションにより既存の列がSUBSTITUTABLE AT ALL LEVELS
とマークされ、列に格納されたインスタンスの型ID用に新しい非表示列が追加されます。その後、変更された型のサブタイプ・インスタンスを列に格納できます。
ALTER
TYPE
文のINVALIDATE
オプションを使用して、依存オブジェクトに加えた型の変更を伝播することなく型の変更ができます。この場合、型の変更によるすべての影響が妥当かどうかを検証する依存型および依存表のチェックは行われません。かわりに、すべての依存スキーマ・オブジェクトは無効とマークされます。型および表も含めて、オブジェクトは、次回の参照時に再検証されます。型の再検証ができない場合、その型は無効のままとなります。また、そのような型を参照する表も、問題が修正されるまではアクセス不可となります。
表が妥当性チェックに失敗するのは、たとえば、次の場合です。型に新しい属性を追加した結果、その表内の一部の列が、最大許容数である1000を超えた場合。ある表のパーティション化キーまたはクラスタ化キーとして使用されている属性が型から削除された場合。
型の再検証は、ALTER TYPE COMPILE
文を発行すると強制的に実行できます。無効な表の再検証を強制的に実行するには、ユーザーは、ALTER TABLE UPGRADE
文を発行して、データを最新の型バージョンに変更するかどうかを指定できます。(表の参照時にトリガーされた表の妥当性チェックにおいて、表データは常に最新の型バージョンになるよう更新されます。データの変換を延期するオプションはありません。)
表を最新の型バージョンに変換できない場合、その表に対するINSERT
文、UPDATE
文およびDELETE
文は使用できません。また、そのデータにはアクセスできなくなります。その表に対して次のDDLは実行できますが、無効な表を参照する他のすべての文は、その表の妥当性が検証されるまで使用できません。
DROP TABLE
TRUNCATE TABLE
ある表の%ROWTYPE
またはある列の%TYPE
、あるいはある表にある属性を使用して定義された変数を含むすべてのPL/SQLプログラムは、最新の型バージョンに基づいてコンパイルされます。その表の再検証が失敗すると、その表を参照する任意のプログラム・ユニットのコンパイルも失敗します。
表8-1に、型の属性またはメソッド定義を変更するために使用するALTER
TYPE
文の一部の重要なオプションを示します。
表8-1 型進化に使用するALTER TYPEオプション
オプション | 説明 |
---|---|
|
すべての依存オブジェクトを無効とします。このオプションを使用すると、型および表のすべてのチェックが迂回されて、時間が節約できます。 このオプションは、依存型および依存表の妥当性チェックにおいて問題が発生しないことが確実な場合に使用してください。表の妥当性が検証されるまでは表データにはアクセスできません。表の妥当性チェックができない場合は、そのデータはアクセス不可のままになります。 |
|
型の変更を依存型および依存表に伝播します。この文は、 他のオプションなしに |
|
すべてのユーザー定義列に格納されているデータを、列の型の最新バージョンに変換します。 列の型に追加された新しい各属性の場合は、新しい属性がデータに追加され、NULLに初期化されます。参照される型から削除される各属性の場合は、対応する属性データが表内の各行から削除されます。表のデータが格納されているすべての表領域は、読取り/書込みモードである必要があります。読取り/書込みモードではない場合、この文の処理は失敗します。 |
|
列データを変換しないで、現行の型バージョンに対応付けられたまま維持します。属性が表が参照する型から削除されても、削除された属性の対応する列は表から削除されません。その列のメタデータが未使用とマークされるのみです。削除された属性が列外(たとえば、 このオプションは、数多くの大きな表があり、1つのトランザクションでそのすべてを変換すると、ロールバック・セグメントが不足する可能性がある場合に使用します。このオプションを使用して、後で、各依存表のデータを、別個のトランザクションで変換できます( このオプションを指定すると、表のデータは、以前の型バージョンの形式のまま維持されるので、表の更新が高速化されます。ただし、この表からデータを選択するには、その列に格納されているイメージを最新の型バージョンに変換する必要があります。この操作は、後続の このオプションは、表のメタデータの更新のみを必要とするため、文を正常に実行するためにすべての表領域の読取り/書込みモードでのオンライン化が必要なわけではありません。 |
|
システムに、依存表および索引からのエラーを無視させます。エラーについては、後で問合せができるように、指定された例外表にログが作成されます。一部の表でエラーが発生した場合、依存表にアクセスできなくなる可能性があるので、このオプションは慎重に使用してください。 |
|
型をFINALからNOT FINALに変更する場合に使用するオプションで、すべてのユーザー定義列に格納されているデータを、最新バージョンの列の型に変換し、作成された型の新しいサブタイプが このオプションを指定せずに、型を |
関連項目 ALTER TYPE オプションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 |
図8-1に、ALTER
TYPE
INVALIDATE
のオプションとその影響を示します。この図で、T1
は型、T2
は依存型です。後述の図に関する注意も参照してください。
図に関する注意:
Invalidate: (1)の線の下のすべてのオブジェクトは無効とマークされます。
Cascade Not Including Table Data: (2)の線の下のすべてのオブジェクトは無効とマークされます。すべての依存表のメタデータを最新の型バージョンにアップグレードしますが、表データは変換されません。
Cascade Including Table Data: (3)の線の下のすべてのオブジェクトは無効とマークされます。表データも含め、すべての依存表が最新の型バージョンにアップグレードされます。
ALTER
TABLE
を使用して、参照される型の最新バージョンに表データを変換できます。表データを最新の型バージョンに変換する例は、「ネストした表属性の追加による型の変更」を参照してください。INCLUDING
DATA
オプションの詳細は、表8-1を参照してください。
関連項目 ALTER TABLE オプションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 |
システム定義の属性値コンストラクタの場合、型の各属性値をコンストラクタに渡す必要があります。すると、例8-6に示すように、コンストラクタにより、新しいオブジェクト・インスタンスの属性にこれらの値が設定されます。
例8-6 コンストラクタによる属性値の設定
CREATE TYPE shape AS OBJECT ( name VARCHAR2(30), area NUMBER); / CREATE TABLE building_blocks of shape; -- Attribute value constructor: Sets instance attributes to the specified values INSERT INTO building_blocks VALUES ( NEW shape('my_shape', 4));
NEW
は、コンストラクタへのコールの前にオプションで追加するキーワードです。このキーワードを追加することをお薦めします。
属性値コンストラクタ・ファンクションを使用することにより、型に対して独自のコンストラクタを定義する必要がなくなります。ただし、属性値コンストラクタを使用する場合は、型に宣言されたすべての属性に対して値を指定する必要があります。指定しない場合、コンストラクタへのコールのコンパイルが失敗します。
たとえば、属性を追加して後で型を進化させる場合は、属性値コンストラクタのこの要件によって問題が発生することがあります。型の属性を変更した場合は、その型の属性値コンストラクタも変更されます。属性を追加した場合、更新された属性値コンストラクタは、新しい属性および古い属性に対する値が指定されるものとみなします。その結果、古い属性に対してのみ値が指定された場合は、既存のコード内の属性値コンストラクタへのすべてのコールのコンパイルが失敗します。
「型進化」を参照してください。
ユーザー定義コンストラクタは、型のすべての属性に対して値を明示的に設定する必要がないため、属性値コンストラクタで発生する問題が回避されます。ユーザー定義コンストラクタは、任意の型の任意の数の引数を取ることができ、これらの引数は型の属性に直接マップする必要がありません。コンストラクタの定義では、属性を任意の適切な値に初期化できます。値が指定されない属性は、システムによってNULL
に初期化されます。
たとえば、属性を追加して型を進化させる場合、その型に対するユーザー定義コンストラクタへのコールは変更する必要がありません。通常のメソッドのようなユーザー定義コンストラクタは、型が進化しても自動的に変更されません。そのため、ユーザー定義コンストラクタのコール・シグネチャは同じ状態のまま維持されます。ただし、新しい属性をNULL
に初期化しない場合は、コンストラクタの定義の変更が必要になることがあります。
ユーザー定義コンストラクタは、通常のメソッド・ファンクションと同様に型本体に定義します。ユーザー定義コンストラクタの宣言および定義は、CONSTRUCTOR FUNCTION
句を使用します。また、RETURN SELF AS RESULT
句も使用する必要があります。
型のコンストラクタには、型と同じ名前を使用する必要があります。例8-7では、shape
型の2つのコンストラクタ・ファンクションを定義します。例に示すとおり、異なるシグネチャを持つ複数のバージョンを定義することにより、ユーザー定義コンストラクタをオーバーロードできます。
例8-7 ユーザー定義コンストラクタの定義および実装
CREATE TYPE shape AS OBJECT ( name VARCHAR2(30), area NUMBER, CONSTRUCTOR FUNCTION shape(SELF IN OUT NOCOPY shape, name VARCHAR2) RETURN SELF AS RESULT, CONSTRUCTOR FUNCTION shape(SELF IN OUT NOCOPY shape, name VARCHAR2, area NUMBER) RETURN SELF AS RESULT ) NOT FINAL; / CREATE TYPE BODY shape AS CONSTRUCTOR FUNCTION shape(SELF IN OUT NOCOPY shape, name VARCHAR2) RETURN SELF AS RESULT IS BEGIN SELF.name := name; SELF.area := 0; RETURN; END; CONSTRUCTOR FUNCTION shape(SELF IN OUT NOCOPY shape, name VARCHAR2, area NUMBER) RETURN SELF AS RESULT IS BEGIN SELF.name := name; SELF.area := area; RETURN; END; END; /
ユーザー定義コンストラクタには、暗黙的な第1パラメータSELF
があります。ユーザー定義コンストラクタの宣言では、このパラメータの指定はオプションです。指定する場合、このパラメータのモードはIN OUT
として宣言する必要があります。
必須句RETURN SELF AS RESULT
によって、戻されるインスタンスの最も狭い意味での型は、必ずSELF
引数の最も狭い意味での型と同じになります。コンストラクタの場合、この型は、コンストラクタが定義された型です。
shape
コンストラクタへのコールに対するSELF
引数の最も狭い意味での型がshape
の場合、この句によってshape
コンストラクタからはshape
のサブタイプのインスタンスではなくshape
のインスタンスが必ず戻されます。
コンストラクタ・ファンクションがコールされると、システムはSELF
引数の属性をNULL
に初期化します。前述の例に示すとおり、ファンクション本体で初期化される後続の属性名は、コンストラクタ・ファンクションの引数の名前と区別するために、SELF
で修飾できます(これらの名前が同一の場合)。引数の名前が異なる場合、このような修飾は不要です。次に例を示します。
SELF.name := name;
または
name := p1;
例に示すとおり、ファンクション本体には、明示的なreturn;
を含める必要があります。ただし、returnキーワードの後に、return
式を続けることはできません。システムは、新しく作成されたSELF
インスタンスを自動的に戻します。
ユーザー定義コンストラクタは、PL/SQL、CまたはJavaで実装できます。
他の型のメソッドと同様、ユーザー定義コンストラクタもオーバーロードできます。
ユーザー定義コンストラクタは継承されないため、スーパータイプで定義されたユーザー定義コンストラクタはサブタイプに隠蔽できません。ただし、ユーザー定義コンストラクタのシグネチャが属性値コンストラクタのシグネチャと完全に一致する場合、ユーザー定義コンストラクタはその型の属性値コンストラクタを隠蔽し、これを置き換えます。シグネチャが一致するには、ユーザー定義コンストラクタのパラメータ(暗黙的なSELF
パラメータの後)の名前と型が、その型の属性の名前と型と同じである必要があります。ユーザー定義コンストラクタの各パラメータ(暗黙的なSELF
パラメータの後)のモードは、必ずIN
にしてください。
同じ名前とシグネチャを持つユーザー定義コンストラクタによって属性値コンストラクタが隠蔽されていない場合は、継続して属性値コンストラクタをコールできます。
たとえば、属性の追加により型が進化する場合は、型の属性値コンストラクタのシグネチャもそれに対応して変更することに注意してください。これによって、以前に隠蔽されていた属性値コンストラクタが再度使用可能になります。
ユーザー定義コンストラクタは、他のすべてのファンクションと同様にコールします。ユーザー定義コンストラクタは、通常のファンクションが使用できるすべての場所で使用できます。
SELF
引数は、暗黙的に渡され、明示的に渡されません。つまり、次のように使用することはできません。
NEW constructor(instance, argument_list)
CREATE
文またはALTER
TABLE
文のDEFAULT
句には、ユーザー定義コンストラクタは指定できませんが、属性値コンストラクタは指定できます。属性値コンストラクタの引数には、PL/SQLファンクションまたは他の列(疑似列LEVEL
、PRIOR
、ROWNUM
など)の参照、あるいは完全に指定されていない日付定数の参照を含めることはできません。CHECK制約式についても同様です。表の作成中または変更中に、属性値コンストラクタはCHECK制約式の一部として使用できますが、ユーザー定義コンストラクタは使用できません。
SQLでは、引数を持たないコンストラクタ・コールについても、カッコを付ける必要があります。PL/SQLでは、引数を持たないコンストラクタを起動する場合、カッコはオプションです。ただし、カッコを付けた方が、コンストラクタ・コールがファンクション・コールであることがより明確になります。次のPL/SQL例では、新しいshapeを作成するためのコンストラクタ・コールのカッコが省略されています。
shape s := NEW my_schema.shape;
NEW
キーワードおよびスキーマ名はオプションで使用してください。
例8-8では、例8-7で作成した型の下にサブタイプを作成し、ユーザー定義コンストラクタをコールする例を示します。
例8-8 ユーザー定義コンストラクタのコール
CREATE TYPE rectangle UNDER shape ( len NUMBER, wth NUMBER, CONSTRUCTOR FUNCTION rectangle(SELF IN OUT NOCOPY rectangle, name VARCHAR2, len NUMBER, wth NUMBER) RETURN SELF as RESULT, CONSTRUCTOR FUNCTION rectangle(SELF IN OUT NOCOPY rectangle, name VARCHAR2, side NUMBER) RETURN SELF as RESULT); / SHOW ERRORS CREATE TYPE BODY rectangle IS CONSTRUCTOR FUNCTION rectangle(SELF IN OUT NOCOPY rectangle, name VARCHAR2, len NUMBER, wth NUMBER) RETURN SELF AS RESULT IS BEGIN SELF.name := name; SELF.area := len*wth; SELF.len := len; SELF.wth := wth; RETURN ; END; CONSTRUCTOR FUNCTION rectangle(SELF IN OUT NOCOPY rectangle, name VARCHAR2, side NUMBER) RETURN SELF AS RESULT IS BEGIN SELF.name := name; SELF.area := side * side; SELF.len := side; SELF.wth := side; RETURN ; END; END; / CREATE TABLE shape_table OF shape; INSERT INTO shape_table VALUES(shape('shape1')); INSERT INTO shape_table VALUES(shape('shape2', 20)); INSERT INTO shape_table VALUES(rectangle('rectangle', 2, 5)); INSERT INTO shape_table VALUES(rectangle('quadrangle', 12, 3)); INSERT INTO shape_table VALUES(rectangle('square', 12));
次の問合せでは、shape_table
内の行を選択します。
SELECT VALUE(s) FROM shape_table s;
VALUE(S)(NAME, AREA)
---------------------------------------------
SHAPE('shape1', 0)
SHAPE('shape2', 20)
RECTANGLE('rectangle', 10, 2, 5)
RECTANGLE('quadrangle', 36, 12, 3)
RECTANGLE('square', 144, 12, 12)
次のPL/SQLコードは、コンストラクタをコールします。
s shape := NEW shape('void');
SQLJオブジェクト型は、JavaクラスにマップされるSQLオブジェクト型です。SQLJオブジェクト型は属性値コンストラクタを持ちます。このオブジェクト型は、参照されたJavaクラスでコンストラクタにマップされるユーザー定義コンストラクタを持つこともできます。
例8-9 SQLJオブジェクトの作成
CREATE TYPE address AS OBJECT EXTERNAL NAME 'university.address' LANGUAGE JAVA USING SQLData( street VARCHAR2(100) EXTERNAL NAME 'street', city VARCHAR2(50) EXTERNAL NAME 'city', state VARCHAR2(50) EXTERNAL NAME 'state', zipcode NUMBER EXTERNAL NAME 'zipcode', CONSTRUCTOR FUNCTION address (SELF IN OUT NOCOPY address, street VARCHAR2, city VARCHAR2, state VARCHAR2, zipcode NUMBER) RETURN SELF AS RESULT AS LANGUAGE JAVA NAME 'university.address (java.lang.String, java.lang.String, java.lang.String, int) return address'); /
シリアル化表現のSQLJ型は、ユーザー定義コンストラクタのみ持つことができます。SQLJ型のオブジェクトの内部表現は、SQLにとって不透明であるため、SQLJ型に属性値コンストラクタは使用できません。
Oracleには、型の記述、データ・インスタンス、およびオブジェクト型やコレクション型を含むその他のSQL型のデータ・インスタンスの集合の動的なカプセル化およびアクセスを可能にする3つの特殊なSQLデータ型があります。この3つの型は、匿名のコレクション型を含めた匿名型の作成にも使用できます。
この3つのSQL型は、不透明型として実装されます。つまり、これらの型の内部構造は、データベースには認識されません。不透明型のデータへの問合せは、目的に合ったファンクション(通常は3GLルーチン)を実装することによってのみ実行されます。Oracleは、そのようなファンクションを実装するためにOCIとPL/SQL APIの両方を提供しています。
表8-2で、この3つの汎用SQL型を説明します。
表8-2 汎用SQL型
型 | 説明 |
---|---|
型記述型。
|
|
自己記述的データ・インスタンスの型。 |
|
自己記述的なデータ集合の型。 |
これらの3つの型はいずれも、データベースに対してネイティブな任意の組込み型と併用できます。また、名前が付いているかどうかにかかわらず、オブジェクト型やコレクション型とも併用できます。これらの型は、型の記述、ローン・インスタンスおよび他の型のインスタンスの集合と動的に連携する汎用手段となります。APIを使用して、任意の型に対して一時的なANYTYPE
記述を作成できます。同様に、任意のSQL型のデータ値を作成またはANYDATA
に変換(キャスト)できます。また、ANYDATA
を、SQL型に変換(して戻すことが)できます。また、値の集合とANYDATASET
の場合も同様です。
汎用型は、ストアド・プロシージャを使用した作業を簡単にします。汎用型を使用して、標準型の記述およびデータをカプセル化し、カプセル化された情報を汎用型のパラメータに渡せます。プロシージャ本体では、カプセル化されたデータおよび任意の型の型記述の処理方法を詳細に記述できます。
また、基礎となる様々な型のカプセル化されたデータを、型ANYDATA
またはANYDATASET
の単一の表の列に格納することもできます。たとえば、ANYDATA
をアドバンスト・キューイングと併用して、異質な型のデータのキューイングをモデル化できます。基礎となるデータ型のデータは、他の任意のデータ同様に、問合せを実行できます。
例8-10では、SYS.ANYDATA
に組み込まれたメソッドを使用して、SYS.ANYDATA
表列に格納されているデータの情報にアクセスするPL/SQLプロシージャを定義して実行します。
例8-10 SYS.ANYDATAの使用
CREATE OR REPLACE TYPE dogowner AS OBJECT ( ownerno NUMBER, ownername VARCHAR2(10) ); / CREATE OR REPLACE TYPE dog AS OBJECT ( breed VARCHAR2(10), dogname VARCHAR2(10) ); / CREATE TABLE mytab ( id NUMBER, data SYS.ANYDATA ); INSERT INTO mytab VALUES ( 1, SYS.ANYDATA.ConvertNumber (5) ); INSERT INTO mytab VALUES ( 2, SYS.ANYDATA.ConvertObject ( dogowner ( 5555, 'John') ) ); commit; CREATE OR REPLACE procedure P IS CURSOR cur IS SELECT id, data FROM mytab; v_id mytab.id%TYPE; v_data mytab.data%TYPE; v_type SYS.ANYTYPE; v_typecode PLS_INTEGER; v_typename VARCHAR2(60); v_dummy PLS_INTEGER; v_n NUMBER; v_dogowner dogowner; non_null_anytype_for_NUMBER exception; unknown_typename exception; BEGIN OPEN cur; LOOP FETCH cur INTO v_id, v_data; EXIT WHEN cur%NOTFOUND; v_typecode := v_data.GetType ( v_type /* OUT */ ); CASE v_typecode WHEN Dbms_Types.Typecode_NUMBER THEN IF v_type IS NOT NULL THEN RAISE non_null_anytype_for_NUMBER; END IF; v_dummy := v_data.GetNUMBER ( v_n /* OUT */ ); Dbms_Output.Put_Line ( To_Char(v_id) || ': NUMBER = ' || To_Char(v_n) ); WHEN Dbms_Types.Typecode_Object THEN v_typename := v_data.GetTypeName(); IF v_typename NOT IN ( 'HR.DOGOWNER' ) THEN RAISE unknown_typename; END IF; v_dummy := v_data.GetObject ( v_dogowner /* OUT */ ); Dbms_Output.Put_Line ( To_Char(v_id) || ': user-defined type = ' || v_typename || '(' || v_dogowner.ownerno || ', ' || v_dogowner.ownername || ' )' ); END CASE; END LOOP; CLOSE cur; EXCEPTION WHEN non_null_anytype_for_NUMBER THEN RAISE_Application_Error ( -20000, 'Paradox: the return AnyType instance FROM GetType ' || 'should be NULL for all but user-defined types' ); WHEN unknown_typename THEN RAISE_Application_Error ( -20000, 'Unknown user-defined type ' || v_typename || ' - program written to handle only HR.DOGOWNER' ); END; / SELECT t.data.gettypename() FROM mytab t; SET SERVEROUTPUT ON; EXEC P;
前述にコード例の問合せおよびプロシージャPにより、次のような出力が生成されます。
T.DATA.GETTYPENAME()
-------------------------------------------------------------
SYS.NUMBER
HR.DOGOWNER
1: NUMBER = 5
2: user-defined type = HR.DOGOWNER(5555, John )
前述の3つの汎用SQL型に対応するのが、それらをモデル化するOCI型です。各OCI型は、それぞれの型の作成およびアクセスに使用する関数のセットを備えています。
OCIType
: SYS.ANYTYPE
に対応しています。
OCIAnyData
: SYS.ANYDATA
に対応しています。
OCIAnyDataSet
: SYS.ANYDATASET
に対応しています。
関連項目
|
Oracleは、レコード集合に対する操作に使用する、MAX
、MIN
、SUM
をはじめとする数多くの定義済集計ファンクションを提供しています。これらの定義済集計ファンクションは、スカラー・データに対してのみ使用できます。ただし、これらのファンクションのカスタム実装を独自に作成できます。または、複雑なデータ(たとえば、オブジェクト型、不透明型、LOB型を使用して格納されているマルチメディア・データなど)に対して使用する新しい集計ファンクションを定義することもできます。
ユーザー定義集計ファンクションは、Oracle独自の組込み集計ファンクションと同様に、SQL DML文で使用されます。このようなファンクションがサーバーに登録されていると、ネイティブのルーチンではなく、ユーザーが定義した集計ルーチンがコールされます。
ユーザー定義集計ファンクションは、スカラー・データに対しても使用できます。たとえば、財務アプリケーションまたは科学アプリケーションに対応付けられた複雑な統計データを処理するために特殊な集計ファンクションを実装すると効果的な場合があります。
ユーザー定義集計ファンクションは、拡張フレームワークの機能です。それらの実装には、ODCIAggregate
インタフェース・ルーチンを使用します。
関連項目 ODCIAggregate インタフェース・ルーチンを使用して、ユーザー定義集計ファンクションを実装する方法については、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください。 |
コレクション型は、C++やJavaなどの言語でのシステム固有の型または構造へ直接マップすることはありません。これらの言語を使用しているアプリケーションは、OCIなどのOracleインタフェースを介して、コレクションの内容にアクセスする必要があります。
一般に、クライアントが(オブジェクトをフェッチすることによって)ネストした表に明示的または暗黙的にアクセスすると、コレクション値全体がクライアント・プロセスに戻されます。パフォーマンス上の理由から、クライアントは、コレクションの内容全体を取り出すのを遅延または回避する場合があります。Oracleでは、ネストした表の実際の値ではなくロケータを使用することによって、これに対処します。実際にコレクションの内容にアクセスが行われたときは、その内容がクライアントに自動的に転送されます。
ネストした表のロケータは、コレクション値へのハンドルに似ています。このロケータは、検索実行時のデータベース・スナップショットを確保することで、ネストした表の値またはコピー・セマンティクスを保とうとします。スナップショットによって、コレクション要素がロケータを使用してフェッチされたときに、データベースがネストした表の値の正しいインスタンスを取り出せるようになります。ロケータの有効範囲は1つのセッションにかぎられ、複数のセッションにまたがって使用することはできません。データベース・スナップショットが使用されているため、ネストした表の更新率が高い場合は、「スナップショットが古すぎます。」
というエラーが発生する場合があります。LOBロケータとは異なり、ネストした表のロケータは純粋なロケータであり、コレクション・インスタンスを変更するためには使用できません。