3 SODA for PL/SQLの使用

SODA for PL/SQLにアクセスする方法と、これを使用してコレクションに対する作成、読取り(取得)および削除(CRUD)操作を実行する方法について説明します。

(CRUD操作は、このドキュメントでは読取りおよび書込み操作とも呼ばれています。)

3.1 SODA for PL/SQLのスタート・ガイド

SODA for PL/SQLにアクセスする方法と、これを使用してデータベース・コレクションを作成し、コレクションにドキュメントを挿入し、コレクションからドキュメントを取得する方法について説明します。

注意:

このトピック内の一部が初見で理解できないことがあっても問題ありません。必要な概念は、別のトピックで詳しくわかるようになっています。このトピックでは、SODAの使用に関する全体的な関連性について説明しています。

SODA for PL/SQLを開始するステップは次のとおりです。

  1. SODA for PL/SQLを使用する際の前提条件が満たされていることを確認します。「SODA for PL/SQLの前提条件」を参照してください。

  2. コレクションの格納に使用するデータベース・スキーマ(ユーザー・アカウント)を特定し、データベース・ロールSODA_APPをそのスキーマに付与します。

    GRANT SODA_APP TO schemaName;
    
  3. 例3-1に示したようなPL/SQLコードを使用して、次の操作を実行します。

    1. デフォルトのコレクション構成(メタデータ)を使用して、コレクション(PL/SQLオブジェクト・タイプSODA_COLLECTION_Tのインスタンス)を作成して開きます。

    2. PL/SQLオブジェクト・タイプSODA_DOCUMENT_Tのインスタンスとして、特定のJSONコンテンでドキュメントを作成します。

    3. ドキュメントをコレクションに挿入します。

    4. 挿入したドキュメントを取り出します。その他のコンポーネント(コンテンツ以外)は、自動的に生成されます。

    5. 一意のドキュメント・キーを出力します。このキーは、自動的に生成されるコンポーネントの1つです。

    6. ドキュメントの挿入をコミットします。

    7. キーを指定して、コレクション内のドキュメントを検索します。

    8. いくつかのドキュメント・コンポーネント(キー、コンテンツ、コンテンツ作成時のタイムスタンプ、最終変更時のタイムスタンプおよびバージョン)を出力します。

  4. コレクションを削除して、そのコレクションとコレクションのメタデータを保存するために使用していたデータベース表をクリーン・アップします。

    SELECT DBMS_SODA.drop_collection('myCollectionName') AS drop_status FROM DUAL;

    警告:

    SQLを使用して、コレクションの基礎になっているデータベースを削除しないでくださいコレクションを削除することは、そのデータベース表を削除することで終わりにはなりません。表に格納されるドキュメント以外にも、コレクションにはOracle Databaseに永続化されるメタデータも含まれています。コレクションの基礎になっている表を削除しても、コレクション・メタデータは削除されません

注意:

ユーザーが作成したPL/SQLサブプログラムからDBMS_SODAパッケージ内のサブプログラムを呼び出す場合や、サブプログラムに定義者(所有者)権限がある場合、データベース管理者(DBA)はサブプログラムにロールSODA_APPを付与する必要があります。たとえば、次のコードでは、所有者がデータベース・スキーマ(ユーザー) my_db_schemaのプロシージャmy_soda_procにロールSODA_APPを付与します。

GRANT SODA_APP TO PROCEDURE my_db_schema.my_soda_proc;

関連項目:

ロールSODA_APPの詳細は、『Oracle Databaseセキュリティ・ガイド』を参照してください

例3-1 最初の演習

DECLARE
    collection      SODA_COLLECTION_T;
    document        SODA_DOCUMENT_T;
    foundDocument   SODA_DOCUMENT_T;
    result_document SODA_DOCUMENT_T;
    docKey          VARCHAR2(100);
    status          NUMBER;
BEGIN
    -- Create a collection.
    collection := DBMS_SODA.create_collection('myCollectionName');

    -- The default collection has BLOB content, so create a BLOB-based document.
    document := SODA_DOCUMENT_T(
                  b_content => utl_raw.cast_to_raw('{"name" : "Alexander"}'));

    -- Insert the document and get it back.
    result_document := collection.insert_one_and_get(document);

    -- The result document has auto-generated components, such as key and version,
    -- in addition to the content.  Print the auto-generated document key.
    docKey := result_document.get_key;
    DBMS_OUTPUT.put_line('Auto-generated key is ' || docKey);

    -- Commit the insert
    COMMIT;

    -- Find the document in the collection by its key
    foundDocument := collection.find_one(docKey);

    -- Get and print some document components: key, content, etc.
    DBMS_OUTPUT.put_line('Document components:');
    DBMS_OUTPUT.put_line('  Key: ' || foundDocument.get_key);
    DBMS_OUTPUT.put_line('  Content: '
                         || utl_raw.cast_to_varchar2(foundDocument.get_blob));
    DBMS_OUTPUT.put_line('  Creation timestamp: ' || foundDocument.get_created_on);
    DBMS_OUTPUT.put_line('  Last-modified timestamp: '
                         || foundDocument.get_last_modified);
    DBMS_OUTPUT.put_line('  Version: ' || foundDocument.get_version);
END;
/

例3-2 最初の演習の出力例

例3-1の結果は、次のように出力されます。自動生成されたコンポーネントの値は、実際の実行では異なります。

Auto-generated key is 96F35328CD3B4F96BF3CD01BCE9EBDF5
Document components:
  Key: 96F35328CD3B4F96BF3CD01BCE9EBDF5
  Content: {"name" : "Alexander"}
  Creation timestamp: 2017-09-19T01:05:06.160289Z
  Last-modified timestamp: 2017-09-19T01:05:06.160289Z
  Version: FD69FB6ACE73FA735EC7922CA4A02DDE0690462583F9EA2AF754D7E342B3EE78

3.2 SODA for PL/SQLによるドキュメント・コレクションの作成

PL/SQLファンクションDBMS_SODA.create_collectionを使用すると、デフォルトのメタデータでドキュメント・コレクションを作成できます。

例3-3は、PL/SQLファンクションDBMS_SODA.create_collectionを使用して、デフォルトのメタデータを含むコレクションを作成します。

デフォルトのコレクション・メタデータには次の特性があります。

  • コレクション内の各ドキュメントには次のドキュメント・コンポーネントがあります。

    • キー(Key)

    • コンテンツ(Content)

    • 作成時のタイムスタンプ(Creation timestamp)

    • 最終変更時のタイムスタンプ(Last-modified timestamp)

    • バージョン(Version)

  • コレクションはJSONドキュメントのみを格納できます。

  • ドキュメント・キーは、コレクションに追加したドキュメントに自動的に生成されます。

ほとんどの場合、デフォルトのコレクション構成をお薦めしますが、コレクションは高度な構成が可能です。コレクションを作成する場合、次のような項目を指定できます。

  • 記憶域の詳細。たとえば、コレクションを格納する表の名前、列の名前とデータ型など。

  • 作成時のタイムスタンプ、最終変更のタイムスタンプおよびバージョン用の列の有無。

  • コレクションがJSONドキュメントのみを格納できるかどうか。

  • ドキュメント・キーの生成方式、およびドキュメント・キーをクライアントで割り当てるかまたは自動的に生成するか。

  • バージョンの生成方式。

このように構成できるため、新しいコレクションを既存の表にマップすることもできます。

デフォルト以外の方法でコレクションを構成するには、DBMS_SODA.create_collectionへの2番目の引数として、JSON表現のカスタム・コレクション・メタデータを指定します。

コレクション構成の詳細を問わない場合は、DBMS_SODA.create_collectionにコレクション名のみを渡します(2番目の引数は渡しません)。これにより、デフォルトの構成でコレクションを作成します。

すでに同じ名前のコレクションが存在する場合は、そのコレクションが開かれ、そのハンドルが返されます。カスタム・メタデータが指定されていて、そのメタデータが既存のコレクションのメタデータと一致しない場合、コレクションは開かれずにエラーが発生します。(一致するには、すべてのメタデータ・フィールドが同じ値を保持している必要があります)。

注意:

特に記載のないかぎり、このドキュメントでは、コレクションはデフォルト構成を使用していると想定しています。

関連項目:

例3-3 デフォルト・メタデータが含まれるコレクションの作成

この例では、デフォルト・メタデータでmyCollectionNameを作成します。

DECLARE
    collection  SODA_Collection_T;
BEGIN
    collection := DBMS_SODA.create_collection('myCollectionName');   
END;
/

3.3 SODA for PL/SQLによる既存のドキュメント・コレクションのオープン

PL/SQLファンクションDBMS_SODA.open_collectionを使用すると、既存のドキュメント・コレクションをオープンできます。

関連項目:

PL/SQLファンクションDBMS_SODA.open_collectionの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください

例3-4 既存のドキュメント・コレクションのオープン

この例では、PL/SQLファンクションDBMS_SODA.open_collectionを使用して、myCollectionNameという名前のコレクションをオープンし、このコレクションを表すSODA_COLLECTION_Tインスタンスを返します。NULL値が返された場合、myCollectionNameという名前のコレクションは存在しません。

DECLARE
    collection  SODA_COLLECTION_T;
BEGIN
    collection := DBMS_SODA.open_collection('myCollectionName');
END;
/

3.4 SODA for PL/SQLによる特定のコレクションの有無の確認

PL/SQLファンクションDBMS_SODA.open_collectionを使用すると、特定のコレクションの存在を確認できます。指定した名前のコレクションが存在しない場合は、SQLのNULL値が返されます。それ以外の場合は、コレクション・オブジェクトが返されます。

関連項目:

PL/SQLファンクションDBMS_SODA.open_collectionの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください

例3-5 特定の名前を持つコレクションの確認

この例では、DBMS_SODA.open_collectionを使用して、myCollectionNameという名前の既存のコレクションを試しにオープンします。該当するコレクションが存在しない場合は、メッセージを出力します。

DECLARE
    collection SODA_COLLECTION_T;
BEGIN
    collection := DBMS_SODA.open_collection('myCollectionName');
    IF collection IS NULL THEN
        DBMS_OUTPUT.put_line('Collection does not exist');
    END IF;
END;
/

3.5 SODA for PL/SQLによる既存のコレクションの検出

PL/SQLファンクションDBMS_SODA.list_collection_namesを使用すると、既存のコレクションを検出できます。

関連項目:

PL/SQLファンクションDBMS_SODA.list_collection_namesの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください

例3-6 すべての既存のコレクションの名前の出力

この例では、PL/SQLファンクションDBMS_SODA.list_collection_namesを使用して、コレクション名のリストを取得します。その後で、そのリストを反復して名前を出力します。

DECLARE
    coll_list  SODA_COLLNAME_LIST_T;
BEGIN
    coll_list := DBMS_SODA.list_collection_names;
    DBMS_OUTPUT.put_line('Number of collections: ' || to_char(coll_list.count));
    DBMS_OUTPUT.put_line('Collection List: ');
    IF (coll_list.count > 0) THEN
        -- Loop over the collection name list
        FOR i IN
            coll_list.first .. coll_list.last
        LOOP
            DBMS_OUTPUT.put_line(coll_list(i));
        END LOOP;  
    ELSE   
        DBMS_OUTPUT.put_line('No collections found');
    END IF;
END;
/

3.6 SODA for PL/SQLによるドキュメント・コレクションの削除

ドキュメント・コレクションを削除するには、PL/SQLファンクションDBMS_SODA.drop_collectionを使用します。

警告:

SQLを使用して、コレクションの基礎になっているデータベースを削除しないでくださいコレクションを削除することは、そのデータベース表を削除することで終わりにはなりません。表に格納されるドキュメント以外にも、コレクションにはOracle Databaseに永続化されるメタデータも含まれています。コレクションの基礎になっている表を削除しても、コレクション・メタデータは削除されません

注意:

SODAを使用する通常のアプリケーションを日常的に使用する場合、コレクションをドロップして再作成する必要はありません。しかし、なんらかの理由でこれを行う必要がある場合は、このガイドラインが適用されます。

多少なりともコレクションを使用しているアプリケーションがある場合は、コレクションをドロップした後に異なるメタデータで再作成しないでください。すべてのライブSODAオブジェクトが解放されるように、コレクションを再作成する前にこのようなアプリケーションをすべて停止します。

コレクションのドロップだけでは、問題は発生しません。ドロップされたコレクションの読取りまたは書込み操作でエラーが発生します。コレクションをドロップして同じメタデータを持つコレクションを再作成しても、問題はありません。ただし、異なるメタデータでコレクションを再作成して、SODAオブジェクトを使用するライブ・アプリケーションが存在する場合、古いコレクションがアクセスされるというリスクがあり、この場合、エラーは発生しません

注意:

DBMS_SODA.drop_collectionを使用する前に、すべての書込みをコミットしてください。削除が成功するには、まず、コミットされていないコレクションへのすべての書込みをコミットするか、ロールバックする必要があります(SQL COMMITまたはROLLBACKを明示的に使用する必要があります)。そうでない場合は、例外が発生します。

関連項目:

PL/SQLファンクションDBMS_SODA.drop_collectionの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください

例3-7 ドキュメント・コレクションのドロップ

この例では、PL/SQLファンクションDBMS_SODA.drop_collectionを使用して、コレクションmyCollectionNameを削除します。

コミットされていない書込み操作があるためにコレクションを削除できない場合は、例外がスローされます。コレクションが正常に削除された場合は、ステータス1が返されます。それ以外の場合、ステータスは0になります。具体的には、指定された名前のコレクションが存在しない場合にステータス0が返されます。例外はスローされません。

DECLARE
    status  NUMBER := 0;
BEGIN
    status := DBMS_SODA.drop_collection('myCollectionName');
END;
/

3.7 SODA for PL/SQLによるドキュメントの作成

SODAドキュメントを作成するには、PL/SQLオブジェクト・タイプSODA_DOCUMENT_Tのコンストラクタを使用します。

SODA for PL/SQLでは、PL/SQLオブジェクト・タイプSODA_DOCUMENT_Tのインスタンスを使用してドキュメントを表します。このオブジェクトは、ドキュメント・コンテンツとその他のドキュメント・コンポーネントの媒体です。

次に、JSONドキュメントのコンテンツの例を示します。

{ "name" :    "Alexander",
  "address" : "1234 Main Street",
  "city" :    "Anytown",
  "state" :   "CA",
  "zip" :     "12345"
}

ドキュメントには次のコンポーネントがあります。

  • キー(Key)

  • コンテンツ(Content)

  • 作成時のタイム・スタンプ(Creation time stamp)

  • 最終変更のタイム・スタンプ(Last-modified time stamp)

  • バージョン(Version)

  • メディア・タイプ(JSONドキュメントの場合、"application/json")

ドキュメントを作成するには、SODA_DOCUMENT_Tのいずれかのコンストラクタを呼び出します。コンストラクタは、作成するドキュメントのコンテンツ・タイプ(VARCHAR2CLOBまたはBLOB)に応じて異なります。

特定のコンテンツ・タイプのドキュメントは、そのタイプのドキュメント用に定義されているコンテンツ列が含まれているコレクションにのみ書込みできます。たとえば、コンテンツ・タイプがBLOBのドキュメントは、BLOBsqlType値を保持するcontentColumnが含まれているコレクションにのみ書込み(挿入または置換)できます。(BLOBは、コレクションのデフォルト・コンテンツ・タイプです)。

ドキュメント・コンストラクタの呼出し方法は様々ありまります。

  • ドキュメントのキーは、最初の引数として指定できます。

    コレクションでは、各ドキュメントにキーが必要です。ドキュメントを作成する場合で、ドキュメントをコレクションに挿入する必要があり、挿入されるドキュメントに対してコレクションで自動的にキーを生成しない場合にのみ、キーを指定する必要があります。デフォルトでは、コレクションは自動的にドキュメント・キーを生成するように構成されます。

  • ドキュメントのコンテンツは、必ず指定します。ドキュメントのキーも指定する場合、コンテンツはコンストラクタの2番目の引数になります。

    コンテンツのみを指定する場合は、コンテンツの仮パラメータと実パラメータの両方を関連付け矢印(=>)で区切って指定する必要があります(コンテンツ・タイプがVARCHAR2の場合はv_content => actualCLOBの場合はc_content => actualBLOBの場合はb_content => actual)。

  • ドキュメントのメディア・タイプを指定できます。デフォルトは"application/json"です。すべてのパラメータ(キー、コンテンツおよびメディア・タイプ)を指定しないかぎり、メディア・タイプの仮パラメータと実パラメータの両方を関連付け矢印(=>)で区切って指定する必要があります(media_type => actual)。

明示的に指定していないパラメータは、NULLにデフォルト設定されます。

ドキュメントのキーを自動的に生成するコレクションに挿入するドキュメントを作成する場合、コンテンツ・パラメータのみを指定すると便利です。クライアントでキーが割り当てられるコレクションに挿入するドキュメントを作成する場合、キーとコンテンツのみを指定すると便利です。JSON以外の("application/json"以外のメディア・タイプを使用する)ドキュメントを作成する場合、(コンテンツと)メディア・タイプを指定すると便利です。

ただし、SODA_DOCUMENT_Tコンストラクタを呼び出すことで、指定したコンポーネント(コンテンツと、キーやメディア・タイプなども)を指定した値に設定します。さらに、作成時のタイムスタンプ、最終更新時のタイムスタンプおよびバージョンの値をSQL NULL値に設定します。

オブジェクト・タイプSODA_DOCUMENT_Tには、getterメソッドがあります(これはゲッターとも呼ばれます)。それぞれのゲッターで、ドキュメントから特定のオブジェクトを取得します。(ゲッターのget_data_type()は、実際にはコンポーネント自体ではなく、コンテンツ・コンポーネントに関する情報を返します)。

表3-1 ドキュメント(SODA_DOCUMENT_T)のgetterメソッド

getterメソッド 説明

get_created_on()

ドキュメントの作成時のタイムスタンプVARCHAR2値として取得します。

get_key()

ドキュメントの一意のキーVARCHAR2値として取得します。

get_last_modified()

ドキュメントの最終変更時のタイム・スタンプVARCHAR2値として取得します。

get_media_type()

ドキュメントのメディア・タイプVARCHAR2値として取得します。

get_version()

ドキュメントのバージョンVARCHAR2値として取得します。

get_blob()

ドキュメントのコンテンツBLOB値として取得します。

ドキュメントのコンテンツは、BLOBデータであることが必要です。それ以外の場合はエラーが発生します。

get_clob()

ドキュメントのコンテンツCLOB値として取得します。

ドキュメントのコンテンツは、CLOBデータであることが必要です。それ以外の場合はエラーが発生します。

get_varchar2()

ドキュメントのコンテンツVARCHAR2値として取得します。

ドキュメントのコンテンツは、VARCHAR2データであることが必要です。それ以外の場合はエラーが発生します。

get_data_type()

ドキュメントのコンテンツのデータ型をPLS_INTEGER値として取得します。VARCHAR2コンテンツの場合、値はDBMS_SODA.DOC_VARCHAR2です。BLOBコンテンツの場合、値はDBMS_SODA.DOC_BLOBです。また、CLOBコンテンツの場合、値はDBMS_SODA.DOC_CLOBです。

ドキュメントの作成直後に、getterメソッドは次の値を返します。

  • コンストラクタに指定した値

  • メソッドget_media_type()の場合は"application/json" (メディア・タイプを指定しなかった場合)

  • その他のコンポーネントの場合はNULL

コンテンツ記憶域のデータ型ごとに、関連付けられたコンテンツ・コンポーネントのgetterメソッドがあります。それぞれの記憶域タイプに該当するgetterメソッドを使用する必要があります(VARCHAR2記憶域にはget_varchar2()CLOB記憶域にはget_clob()BLOB記憶域にはget_blob())。そうでない場合は、エラーが発生します。

例3-8では、コンテンツのみを指定してSODA_DOCUMENT_Tインスタンスを作成します。メディア・タイプは"application/json"にデフォルト設定されます。また、その他のドキュメント・コンポーネントはNULLにデフォルト設定されます。

例3-9では、ドキュメントのキーとコンテンツを指定してSODA_DOCUMENT_Tインスタンスを作成します。メディア・タイプは"application/json"にデフォルト設定されます。また、その他のドキュメント・コンポーネントはNULLにデフォルト設定されます。

関連項目:

例3-8 JSONコンテンツを含むドキュメントの作成

この例では、コンテンツ・タイプごとのSODA_DOCUMENT_Tのコンストラクタを使用して3つのドキュメントを作成します。この例では、ドキュメント・コンテンツのみを指定しています(それぞれに同じコンテンツを使用します)。

コンテンツ・パラメータは、それぞれの場合で異なります(コンテンツの格納に使用するSQLデータ型を指定します)。ここでは、最初のコンテンツ・パラメータにv_contentを使用して、VARCHAR2コンテンツを指定しています。2番目にはパラメータc_contentを使用して、CLOBコンテンツを指定しています。3番目にはパラメータb_contentを使用して、BLOBコンテンツを指定しています。

各ドキュメントの作成後に、この例では、getterメソッドを使用してドキュメントのコンテンツを取得します。それぞれのコンテンツ記憶域タイプに応じたgetterメソッドが使用されている点に注目してください(BLOBコンテンツにはget_blob()など)。

コンテンツ・タイプがBLOBのドキュメントが、例3-3で作成したコレクションへの書込みに適しています。このコレクション(デフォルトのメタデータを持つ)は、BLOBコンテンツのドキュメント(のみ)を受け入れるためです。このコレクションに対して、それ以外の2つのドキュメントは適切ではありません。それらを挿入しようとすると、エラーが発生します。

DECLARE
    v_doc  SODA_DOCUMENT_T;
    b_doc  SODA_DOCUMENT_T;
    c_doc  SODA_DOCUMENT_T;
BEGIN
    -- Create VARCHAR2 document
    v_doc := SODA_DOCUMENT_T(v_content => '{"name" : "Alexander"}');
    DBMS_OUTPUT.put_line('Varchar2 Doc content: ' || v_doc.get_varchar2);
    
    -- Create BLOB document
    b_doc := SODA_DOCUMENT_T(
               b_content => utl_raw.cast_to_raw('{"name" : "Alexander"}'));
    DBMS_OUTPUT.put_line('Blob Doc content: ' ||
                         utl_raw.cast_to_varchar2(b_doc.get_blob));

    -- Create CLOB document
    c_doc := SODA_DOCUMENT_T(c_content => '{"name" : "Alexander"}');
    DBMS_OUTPUT.put_line('Clob Doc content: ' || c_doc.get_clob);
END;
/

例3-9 ドキュメント・キーおよびJSONコンテンツを含むドキュメントの作成

この例は、例3-8と似ていますが、ドキュメント・コンテンツとともにドキュメント・キー(myKey)も指定しています。

DECLARE
    v_doc  SODA_DOCUMENT_T;
    b_doc  SODA_DOCUMENT_T;
    c_doc  SODA_DOCUMENT_T;
BEGIN
    -- Create VARCHAR2 document
    v_doc := SODA_DOCUMENT_T('myKey' , v_content => '{"name" : "Alexander"}');
    DBMS_OUTPUT.put_line('Varchar2 Doc key: ' || v_doc.get_key);
    DBMS_OUTPUT.put_line('Varchar2 Doc content: ' || v_doc.get_varchar2);
        
    -- Create BLOB document
    b_doc := SODA_DOCUMENT_T('myKey' ,
                             b_content => utl_raw.cast_to_raw('{"name" : "Alexander"}'));
    DBMS_OUTPUT.put_line('Blob Doc key: ' || b_doc.get_key);
    DBMS_OUTPUT.put_line('Blob Doc content: ' ||
                         utl_raw.cast_to_varchar2(b_doc.get_blob));
    
    -- Create CLOB document
    c_doc := SODA_DOCUMENT_T('myKey' , c_content => '{"name" : "Alexander"}');
    DBMS_OUTPUT.put_line('Clob Doc key: ' || c_doc.get_key);
    DBMS_OUTPUT.put_line('Clob Doc content: ' || c_doc.get_clob);
END;
/

3.8 SODA for PL/SQLによるコレクションへのドキュメントの挿入

コレクションにドキュメントを挿入するには、SODA_COLLECTION_Tのメソッド(メンバー・ファンクション) insert_one()またはinsert_one_and_get()を呼び出します。コレクションがクライアント割当てキーで構成されておらず、入力ドキュメントがキーを指定していない場合、これらのメソッドでは、ドキュメント・キーが自動的に作成されます。

メソッドinsert_one()とメソッドinsert_one_and_get()は、どちらもコレクションにドキュメントを挿入して、作成時のタイムスタンプ、最終変更時のタイムスタンプおよびバージョンの値を自動的に設定します(これらのコンポーネントが含まれるようにしてバージョンが自動的に生成されるようにコレクションを構成した場合。これはデフォルトの構成です)。

ドキュメントを挿入すると、現在の値がNULLのドキュメント・コンポーネント(それらのコンポーネントの値を指定しないでドキュメントを作成した結果の値)は、自動生成される適切な値に更新されます。その後、ドキュメントに対するその他のSODA操作では、最終更新時のタイムスタンプとバージョンのコンポーネントが自動的に更新されます。

ドキュメントの挿入に加えて、insert_one_and_getは結果のドキュメントも返します。これには、生成されたドキュメント・コンポーネント(キーなど)が含まれていますが、挿入したドキュメントのコンテンツは含まれていません。

注意:

コレクションがクライアント割当てドキュメント・キーで構成されていて(デフォルトの場合と異なるケース)、入力ドキュメントがコレクション内の既存のドキュメントを識別するキーを提供している場合、これらのメソッドは例外をスローします。

関連項目:

例3-10 コレクションへのドキュメントの挿入

この例では、ドキュメントを作成して、SODA_COLLECTION_Tのメソッドinsert_one()を使用してコレクションに挿入します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    status      NUMBER;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');
    document := SODA_DOCUMENT_T(
                  b_content => utl_raw.cast_to_raw('{"name" : "Alexander"}'));

    -- Insert a document
    status := collection.insert_one(document);
END;
/

例3-11 コレクションへのドキュメントの挿入および結果ドキュメントの取得

この例では、ドキュメントを作成して、メソッドinsert_one_and_get()を使用してコレクションに挿入します。その後で、結果のドキュメントから生成されたコンポーネント(結果に含まれる)を取得(および出力)します。コンポーネントを取得するために、SODA_DOCUMENT_Tのメソッドget_key()get_created_on()get_last_modified()およびget_version()を使用します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    ins_doc     SODA_DOCUMENT_T;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');
    document := SODA_DOCUMENT_T(
                  b_content => utl_raw.cast_to_raw('{"name" : "Alexander"}'));
    ins_doc := collection.insert_one_and_get(document);

    -- Insert the document and get its components
    IF ins_doc IS NOT NULL THEN
        DBMS_OUTPUT.put_line('Inserted document components:');
        DBMS_OUTPUT.put_line('Key: ' || ins_doc.get_key);
        DBMS_OUTPUT.put_line('Creation timestamp: ' || ins_doc.get_created_on);
        DBMS_OUTPUT.put_line('Last modified timestamp: '
                             || ins_doc.get_last_modified);
        DBMS_OUTPUT.put_line('Version: ' || ins_doc.get_version);
    END IF;
END;
/

3.9 SODA for PLSQLの読取りおよび書込み操作

SODA_OPERATION_Tインスタンスは、SODA_COLLECTION_Tのメソッドfind()によって返されます。SODA_OPERATION_Tのメソッドをつなげて、コレクションに対して読取りおよび書込み操作を指定できます。

注意:

データ型SODA_OPERATION_Tは、Oracle Database 18.3でSODA for PL/SQLに追加されました。これを使用するにはそのデータベース・リリース以降が必要となります。

通常、SODA_OPERATION_Tを使用して、挿入以外のSODAのすべての読取りおよび書込み操作を指定します。SODA_OPERATION_Tの非ターミナル・メソッドをつないで、スコープまたは条件を絞り込んだり、読取りまたは書込み操作を限定したりします。

非ターミナル・メソッドは、それらが呼び出されたインスタンスと同じSODA_OPERATION_Tインスタンスを返すため、それらをつなぐことができます。非ターミナル・メソッドは、key()keys()filter()version()skip()およびlimit()です。

チェーンの最後のSODA_OPERATION_Tターミナル・メソッドでは、実際の読取りまたは書込み操作が実行されます。読取り操作のメソッドは、get_cursor()get_one()およびcount()です。書込み操作のメソッドは、replace_one()replace_one_and_get()およびremove()です。

ドキュメントに記述がなければ、すべての非ターミナル・メソッドをつなぎ、ターミナル・メソッドでチェーンを終了できます。ただし、すべての組合せに意味があるわけではありません。たとえば、keys()などのドキュメントを一意に識別しないメソッドとversion()メソッドをつなげても意味がありません。

関連項目:

SODA_OPERATION_T (各メソッドを含む)の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください

3.10 SODA for PL/SQLによるコレクション内のドキュメントの検索

SODA_OPERATION_Tのターミナル・メソッドget_one()またはget_cursor()を使用すると、コレクション内の1つまたは複数のドキュメントをそれぞれ検索できます。ターミナル・メソッドcount()を使用すると、コレクション内のドキュメントをカウントできます。key()keys()filter()などの非ターミナル・メソッドを使用すると、検索操作の条件を指定できます。

注意:

データ型SODA_OPERATION_Tは、Oracle Database 18.3でSODA for PL/SQLに追加されました。これを使用するにはそのデータベース・リリース以降が必要となります。

関連項目:

例3-12 コレクション内のすべてのドキュメントの検索

この例では、SODA_COLLECTION_Tのメソッドfind()およびgetCursor()を使用して、コレクション内の各ドキュメントを含む問合せ結果リストのカーソルを取得しています。次にWHILE文のカーソルを使用し、結果リスト内の各ドキュメントのコンテンツを文字列として取得して出力します。最後にカーソルをクローズします。

出力するドキュメント・コンポーネントを取得するために、SODA_DOCUMENT_Tのメソッドget_key()get_blob()get_created_on()get_last_modified()およびget_version()が使用されています。ドキュメントのコンテンツをSQL/JSONファンクションのjson_queryに渡し、整形出力します(キーワードPRETTYを使用)。

注意:

リソース・リークを回避するには、不要なカーソルをすべてクローズします

DECLARE
    collection    SODA_COLLECTION_T;
    document      SODA_DOCUMENT_T;
    cur           SODA_CURSOR_T;
    status        BOOLEAN;
BEGIN
    -- Open the collection to be queried
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Open the cursor to fetch the documents
    cur := collection.find().get_cursor();

    -- Loop through the cursor
    WHILE cur.has_next
    LOOP
      document := cur.next;
      IF document IS NOT NULL THEN
          DBMS_OUTPUT.put_line('Document components:');
          DBMS_OUTPUT.put_line('Key: ' || document.get_key);
          DBMS_OUTPUT.put_line('Content: ' || json_query(document.get_blob, '$' PRETTY));
          DBMS_OUTPUT.put_line('Creation timestamp: ' || document.get_created_on);
          DBMS_OUTPUT.put_line('Last modified timestamp: ' || document.get_last_modified);
          DBMS_OUTPUT.put_line('Version: ' || document.get_version);
      END IF;
    END LOOP;

    -- IMPORTANT: You must close the cursor, to release resources.
    status := cur.close;
END;
/

例3-13 ドキュメント・キーを付与した一意のドキュメントの検索

この例では、SODA_COLLECTION_Tのメソッドfind()key()およびget_one()を使用して、キーが"key1"の一意のドキュメントを検索します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Find a document using a key
    document := collection.find().key('key1').get_one;

    IF document IS NOT NULL THEN
        DBMS_OUTPUT.put_line('Document components:');
        DBMS_OUTPUT.put_line('Key: ' || document.get_key);
        DBMS_OUTPUT.put_line('Content: ' || JSON_QUERY(document.get_blob, '$' PRETTY));
        DBMS_OUTPUT.put_line('Creation timestamp: ' || document.get_created_on);
        DBMS_OUTPUT.put_line('Last modified timestamp: ' || document.get_last_modified);
        DBMS_OUTPUT.put_line('Version: ' || document.get_version);
    END IF;
END;
/

例3-14 ドキュメント・キーを指定した複数のドキュメントの検索

この例では、(文字列の)キー"key1""key2"および"key3"を指定してキーリストmyKeysを定義します。その後、それらのキーを持つドキュメントが検索され、それらのコンポーネントが出力されます。SODA_COLLECTION_Tのメソッドkeys()では、特定のキーのドキュメントを指定します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    cur         SODA_CURSOR_T;
    status      BOOLEAN;
    myKeys      SODA_KEY_LIST_T;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Set the keys list
    myKeys := SODA_KEY_LIST_T('key1', 'key2', 'key3');

    -- Find documents using keys
    cur := collection.find().keys(myKeys).get_cursor;

    -- Loop through the cursor
    WHILE cur.has_next
    LOOP
      document := cur.next;
      IF document IS NOT NULL THEN
          DBMS_OUTPUT.put_line('Document components:');
          DBMS_OUTPUT.put_line('Key: ' || document.get_key);
          DBMS_OUTPUT.put_line('Content: ' || json_query(document.get_blob, '$' PRETTY));
          DBMS_OUTPUT.put_line('Creation timestamp: ' || document.get_created_on);
          DBMS_OUTPUT.put_line('Last modified timestamp: ' || document.get_last_modified);
          DBMS_OUTPUT.put_line('Version: ' || document.get_version);
      END IF;
    END LOOP;
    status := cur.close;
END;
/

例3-15 フィルタ仕様によるドキュメントの検索

SODA_COLLECTION_Tのメソッドfilter()では、コレクション内のJSONドキュメントをフィルタする強力な方法を提供します。そのパラメータはJSONの例による問合せ(QBE、フィルタ仕様とも呼ばれる)です。

フィルタ指定の構文には、表現力のあるJSONドキュメントのパターン・マッチング言語を使用します。この例では、SODA for PL/SQLでQBEを使用する方法を示すためだけの非常に簡単なQBEのみを使用しています。

この例では、次の操作を行います。

  1. nameフィールドの値が"Alexander"のすべてのJSONドキュメントを検索するフィルタ仕様を作成します。

  2. フィルタ仕様を使用して一致するドキュメントを検索します。

  3. 各ドキュメントのコンポーネントを出力します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    cur         SODA_CURSOR_T;
    status      BOOLEAN;
    qbe         VARCHAR2(128);
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Define the filter specification (QBE)
    qbe := '{"name" : "alexander"}';

    -- Open a cursor for the filtered documents
    cur := collection.find().filter(qbe).get_cursor;

    -- Loop through the cursor
    WHILE cur.has_next
    LOOP
      document := cur.next;
      IF document IS NOT NULL THEN
          DBMS_OUTPUT.put_line('Document components:');
          DBMS_OUTPUT.put_line('Key: ' || document.get_key);
          DBMS_OUTPUT.put_line('Content: ' || JSON_QUERY(document.get_blob, '$' PRETTY));
          DBMS_OUTPUT.put_line('Creation timestamp: ' || document.get_created_on);
          DBMS_OUTPUT.put_line('Last modified timestamp: ' || document.get_last_modified);
          DBMS_OUTPUT.put_line('Version: ' || document.get_version);
      END IF;
    END LOOP;
    status := cur.close;
END;
/

関連項目:

例3-16 メソッドskip()とlimit()を使用したページ区切り問合せの指定

この例では、ページ区切り問合せでSODA_COLLECTION_Tのメソッドfilter()skip()およびlimit()を使用しています。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    cur         SODA_Cursor_T;
    status      BOOLEAN;
    qbe         VARCHAR2(128);
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Define the filter
    qbe := '{"name" : "Alexander"}';

    -- Find all documents that match the QBE, skip over the first 1000 of them,
    -- limit the number of returned documents to 100
    cur := collection.find().filter(qbe).skip(1000).limit(100).get_cursor;

    -- Loop through the cursor
    WHILE cur.has_next
    LOOP
      document := cur.next;
      IF document IS NOT NULL THEN
          DBMS_OUTPUT.put_line('Document components:');
          DBMS_OUTPUT.put_line('Key: ' || document.get_key);
          DBMS_OUTPUT.put_line('Content: ' ||
                               JSON_QUERY(document.get_blob, '$' PRETTY));
          DBMS_OUTPUT.put_line('Creation timestamp: ' || 
                               document.get_created_on);
          DBMS_OUTPUT.put_line('Last modified timestamp: ' ||
                               document.get_last_modified);
          DBMS_OUTPUT.put_line('Version: ' || document.get_version);
      END IF;
    END LOOP;
    status := cur.close;
END;
/

例3-17 ドキュメント・バージョンの指定

この例では、SODA_COLLECTION_Tのメソッドversion()を使用して、ドキュメント・バージョンを指定しています。これは、書込み操作用のターミナル・メソッドとともに使用する場合、オプティミスティック・ロックの実装に便利です。

通常、version()は、ドキュメントを指定するkey()メソッドと一緒に使用します。keyLike()メソッドおよびfilter()メソッドとともにversion()を使用することもできます(1つのドキュメントのみが識別される場合)。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Find a particular version of the document that has a given key
    document := collection.find().key('key1').version('version1').get_one;

    IF document IS NOT NULL THEN
        DBMS_OUTPUT.put_line('Document components:');
        DBMS_OUTPUT.put_line('Key: ' || document.get_key);
        DBMS_OUTPUT.put_line('Content: ' ||
                             JSON_QUERY(document.get_blob, '$' PRETTY));
        DBMS_OUTPUT.put_line('Creation timestamp: ' || document.get_created_on);
        DBMS_OUTPUT.put_line('Last modified timestamp: ' ||
                             document.get_last_modified);
        DBMS_OUTPUT.put_line('Version: ' || document.get_version);
    END IF;
END;
/

例3-18 見つかったドキュメントの数のカウント

この例では、SODA_COLLECTION_Tのメソッドcount()を使用して、コレクション内のすべてのドキュメントの数を取得します。その後、フィルタ指定(QBE)によって返されたすべてのドキュメントの件数が取得されます。

DECLARE
    collection  SODA_COLLECTION_T;
    num_docs    NUMBER;
    qbe         VARCHAR2(128);
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Get a count of all documents in the collection
    num_docs := collection.find().count;
    DBMS_OUTPUT.put_line('Count: ' || num_docs);
    
    -- Set the filter
    qbe := '{"name" : "Alexander"}';

    -- Get a count of all documents in the collection that match a filter spec
    num_docs := collection.find().filter(qbe).count;
    DBMS_OUTPUT.put_line('Count: ' || num_docs);
END;
/

3.11 SODA for PL/SQLによるコレクション内のドキュメントの置換

SODA_OPERATION_Tの置換操作メソッドreplace_one()またはreplace_one_and_get()を非ターミナル・メソッドkey()とつなぐと、置換されるドキュメントを一意に識別できます。必要に応じて、version()filter()などの追加の非ターミナル・メソッドを使用できます。

注意:

データ型SODA_OPERATION_Tは、Oracle Database 18.3でSODA for PL/SQLに追加されました。これを使用するにはそのデータベース・リリース以降が必要となります。

replace_one()メソッドおよびreplace_one_and_get()メソッドは、コンテンツを置き換えるだけでなく、最終変更のタイムスタンプとバージョンの値を更新します。置き換えてもドキュメント・キーまたは作成時のタイムスタンプは変更されません

関連項目:

例3-19 コレクション内の特定のキーを持つドキュメントの置換と結果ドキュメントの取得

この例では、コレクション内の特定のキーを持つドキュメントを置換します。その後で、結果のドキュメントからキーと生成されたコンポーネントを取得(および出力)します。コンポーネントを取得するために、SODA_DOCUMENT_Tのメソッドget_key()get_created_on()get_last_modified()およびget_version()を使用します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    new_doc     SODA_DOCUMENT_T;
BEGIN
    collection := DBMS_SODA.open_collection('myCollectionName');
    document := SODA_DOCUMENT_T(
                  b_content => utl_raw.cast_to_raw('{"name" : "Sriky"}'));
    new_doc := collection.find().key('key1').replace_one_and_get(document);

    IF new_doc IS NOT NULL THEN
        DBMS_OUTPUT.put_line('Document components:');
        DBMS_OUTPUT.put_line('Key: ' || new_doc.get_key);
        DBMS_OUTPUT.put_line('Creation timestamp: ' || new_doc.get_created_on);
        DBMS_OUTPUT.put_line('Last modified timestamp: ' ||
                             new_doc.get_last_modified);
        DBMS_OUTPUT.put_line('Version: ' || new_doc.get_version);
    END IF;
END;
/

例3-20 特定バージョンのドキュメントの置換

ドキュメントを置き換える場合にオプティミスティック・ロックを実装するには、この例のようにメソッドkey()およびversion()をつなげることができます。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    new_doc     SODA_DOCUMENT_T;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Replace version 'version1' of the document that has key 'key1'
    new_doc := SODA_DOCUMENT_T(
                  b_content => utl_raw.cast_to_raw('{"name" : "Sriky"}'));
    document := collection.find().key('key1').version('version1').replace_one_and_get(new_doc);

    IF document IS NOT NULL THEN
        DBMS_OUTPUT.put_line('Document components:');
        DBMS_OUTPUT.put_line('Key: ' || document.get_key);
        DBMS_OUTPUT.put_line('Content: ' ||
                             JSON_QUERY(document.get_blob, '$' PRETTY));
        DBMS_OUTPUT.put_line('Creation timestamp: ' || document.get_created_on);
        DBMS_OUTPUT.put_line('Last modified timestamp: ' ||
                             document.get_last_modified);
        DBMS_OUTPUT.put_line('Version: ' || document.get_version);
    END IF;
END;
/

3.12 SODA for PL/SQLによるコレクションからのドキュメントの削除

SODA_OPERATION_Tのメソッドremove()を非ターミナル・メソッドkey()keys()またはfilter()とつないで、削除するドキュメントを識別することにより、コレクションからドキュメントを削除できます。必要に応じて、version()などの追加の非ターミナル・メソッドを使用できます。

注意:

データ型SODA_OPERATION_Tは、Oracle Database 18.3でSODA for PL/SQLに追加されました。これを使用するにはそのデータベース・リリース以降が必要となります。

関連項目:

例3-21 ドキュメント・キーによるコレクションからのドキュメントの削除

この例では、ドキュメントのキーが"key1"のドキュメントを削除します。削除ステータス(ドキュメントが削除された場合は1、それ以外の場合は0)が出力されます。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    status      NUMBER;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Remove document that has key 'key1'
    status := collection.find().key('key1').remove;

    -- Count is 1 if  document was found
    IF status = 1 THEN
        DBMS_OUTPUT.put_line('Document was removed!');
    END IF;
END;
/

例3-22 特定バージョンのドキュメントの削除

ドキュメントを削除する場合にオプティミスティック・ロックを実装するには、この例のようにメソッドkey()およびversion()をつなげることができます。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    status      NUMBER;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Remove version 'version1' of the document that has key 'key1'.
    status := collection.find().key('key1').version('version1').remove;

    -- Count is 1, if specified version of document with key 'key1' is found
    IF status = 1 THEN
        DBMS_OUTPUT.put_line('Document was removed!');
    END IF;
END;
/

例3-23 ドキュメント・キーによるコレクションからのドキュメントの削除

この例では、キーがkey1key2およびkey3のドキュメントを削除します。

DECLARE
    collection  SODA_COLLECTION_T;
    document    SODA_DOCUMENT_T;
    cur         SODA_CURSOR_T;
    num_docs    NUMBER;
    myKeys      SODA_KEY_LIST_T;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Define the keys list
    myKeys := SODA_KEY_LIST_T('key1','key2','key3');

    -- Remove documents using keys
    num_docs := collection.find().keys(myKeys).remove;

    DBMS_OUTPUT.put_line('Number of documents removed: ' || num_docs);
END;
/

例3-24 フィルタによるコレクションからのJSONドキュメントの削除

この例では、フィルタを使用してgreetingフィールドの値が"hello"であるJSONドキュメントを削除します。その後、削除されたドキュメントの数を出力します。

DECLARE
    collection  SODA_COLLECTION_T;
    num_docs    NUMBER;
    qbe         VARCHAR2(128);
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Define the filter specification
    qbe := '{ "greeting" : "hello" }';

    -- Get a count of all documents in the collection that match the QBE
    num_docs := collection.find().filter(qbe).remove;
    DBMS_OUTPUT.put_line('Number of documents removed: ' || num_docs);
END;
/

3.13 SODA for PL/SQLによるコレクション内のドキュメントの索引付け

SODAコレクション内のドキュメントを索引付けするには、SODA_COLLECTION_Tのメソッドcreate_index()を使用します。その入力パラメータはテキストのJSON索引指定です。これにより、Bツリー、空間、全文および非定型の索引付けのサポートを指定し、JSONデータ・ガイドのサポートを指定できます。

注意:

索引付けに対するSODA for PL/SQLのサポートはOracle Database 18.3で追加されました。このSODA機能を使用するには、そのデータベース・リリース以降が必要となります。

SODAコレクションに対する索引を削除するには、SODA_COLLECTION_Tのメソッドdrop_Index()を使用します。

JSON検索索引は、全文問合せおよび非定型構造問合せに使用され、永続的な記録およびJSONデータ・ガイド情報の自動更新に使用されます。

Oracle Spatial and Graph索引はGeoJSON (空間)データに使用されます。

関連項目:

例3-25 SODA for PL/SQLによるJSONフィールドに対するBツリー索引の作成

この例では、コレクションmyCollectionName内のJSONドキュメントの数値フィールドaddress.zipに対して一意ではないBツリー索引を作成しています。

DECLARE
    collection  SODA_COLLECTION_T;
    spec        VARCHAR2(700);
    status      NUMBER;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Define the index specification
    spec := '{"name"   : "ZIPCODE_IDX",
              "fields" : [{"path"     : "address.zip",
                           "datatype" : "number",
                           "order"    : "asc"}]}';
    -- Create the index
    status := collection.create_index(spec);
    DBMS_OUTPUT.put_Line('Status: ' || status);
END;
/

例3-26 SODA for PL/SQLによるJSON検索索引の作成

この例では、アドホック問合せおよび全文検索(QBE演算子$containsを使用した問合せ)のためにコレクションmyCollectionNameのドキュメントを索引付けし、JSONドキュメントに関するデータ・ガイド情報を自動的に累計および更新します(構造およびタイプ情報を集計します)。索引指定のフィールドはnameのみです(fieldsフィールドは指定しません)。

DECLARE
    collection  SODA_COLLECTION_T;
    spec        VARCHAR2(700);
    status      NUMBER;
BEGIN
    -- Open the collection
    collection := DBMS_SODA.open_collection('myCollectionName');

    -- Define the index specification
    indexSpec := '{"name" : "SEARCH_AND_DATA_GUIDE_IDX"}';
               
    -- Create the index
    status := collection.create_index(indexSpec);
    DBMS_OUTPUT.put_Line('Status: ' || status);
END;
/

ここで使用されている単純な索引指定は、デフォルト値を明示的に使用した次の指定と同じです。

{"name" : "SEARCH_AND_DATA_GUIDE_IDX",
 "dataguide" : "on",
 "search_on" : "text_value"}

かわりに非定型のみ(検索)の索引付けを行う場合は、dataguideフィールドに値"off"を明示的に指定します。かわりにデータ・ガイドのみをサポートする場合は、search_onフィールドに値"none"を明示的に指定します。

注意:

データ・ガイド対応JSON検索索引を作成する、または既存のJSON検索索引をデータ・ガイド対応にするには、データベース権限CTXAPPおよびOracle Databaseリリース12c (12.2.0.1)以降が必要です。

例3-27 SODA for PL/SQLによる索引の削除

SODAコレクションに対する索引を削除するには、SODA_COLLECTION_Tのメソッドdrop_index()に索引名を渡します。この例では、索引myIndexを削除しています。

DECLARE
    coll    SODA_COLLECTION_T;
    status  NUMBER;
BEGIN
    -- Open the collection
    coll := dbms_soda.open_Collection('myCollectionName');

    -- Drop the index using name
    status := coll.drop_index('myIndex');
    DBMS_OUTPUT.put_Line('Status: ' || status);
END;
/

3.14 SODA for PL/SQLによるコレクションのデータ・ガイドの取得

コレクションのデータ・ガイドを取得するには、SODA_COLLECTION_Tのメソッドget_Data_Guide()を使用します。データ・ガイドは、コレクション内のJSONドキュメントの構造およびタイプ情報をまとめたJSONドキュメントです。これらの文書内で使用されているフィールドに関するメタデータを記録します。

注意:

JSONデータ・ガイドに対するSODA for PL/SQLのサポートは、Oracle Database 18.3で追加されました。このSODA機能を使用するには、そのデータベース・リリース以降が必要となります。

コレクションのデータ・ガイドを取得する前に、データ・ガイド対応のJSON検索索引を作成する必要があります。この方法を例3-26に示します。

例3-28 SODA for PL/SQLによるデータ・ガイドの取得

この例では、SODA_COLLECTION_Tのメソッドget_Data_Guide()を使用して、コレクションMyCollectionNameのデータ・ガイドを取得しています。その後、SQL/JSONファンクションjson_queryを使用して、データ・ガイド・ドキュメントのコンテンツを整形出力します。最後に、データ・ガイド・ドキュメントに使用されている一時LOBが解放されます。

DECLARE
    collection   SODA_COLLECTION_T;
    dataguide    CLOB;
BEGIN
    -- Open the collection.
    collection := dbms_soda.open_Collection('myCollectionName');
    
    -- Get the data guide for the collection.
    dataguide := collection.get_Data_Guide;
    DBMS_OUTPUT.put_line(json_query(dataguide, '$' pretty));
    
    -- Important: Free the temporary LOB.
    IF dbms_lob.isTemporary(dataguide) = 1
    THEN
        dbms_lob.freeTemporary(dataguide);
    end if;   
END;
/

3.15 SODA for PL/SQLによるトランザクションの処理

通常のPL/SQLやSQLのように、個別のSODA読取りおよび書込み操作(または、それらの操作のグループ)をトランザクションとして処理できます。トランザクションをコミットするには、SQL COMMIT文を使用します。変更をロールバックする場合は、SQL ROLLBACK文を使用します。

SODA操作のDBMS_SODA.create_collectionDBMS_SODA.drop_collectionでは、そのアクションの実行前後に自動的にコミットされません。これは、アクションの実行前後にコミットするSQL DDL文の動作とは異なります。

この結果の1つとして、SODAコレクションの削除前には、未処理の書込み操作を明示的にコミットするかロールバックする必要があります。そのために、明示的にSQL COMMITまたはROLLBACKを使用する必要があります。その理由は、DBMS_SODA.drop_collectionはアクションの実行前にコミットを発行しないためです。この点で、DBMS_SODA.drop_collectionの動作はSQL DROP TABLE文の動作と異なります。

関連項目:

例3-29 SODAドキュメントの挿入と置換に関連するトランザクション

この例は、無名PL/SQLブロック内で使用しているSQL COMMIT文およびROLLBACK文を示しています。ここでは、SODAコレクションを開いて、ドキュメントを挿入してから、そのコンテンツを置換します。ドキュメントの挿入操作とドキュメント・コンテンツの置換操作の組合せはアトミックです(つまり、単一のトランザクションです)。

DECLARE
    collection SODA_COLLECTION_T;
    status NUMBER;
BEGIN
    collection := DBMS_SODA.open_collection('myCollectionName');
    status := collection.insert_one(
                SODA_Document_T(
                  b_content => utl_raw.cast_to_raw('{"a":"aval","b":"bval","c":"cval"}'));
    status := collection.replace_one('key1', SODA_DOCUMENT_T('{"x":"xval","y":"yval"}'));
    -- Commit the transaction
    COMMIT;
    DBMS_OUTPUT.put_line('Transaction is committed');
-- Catch exceptions and roll back if an error is raised
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.put_line (SQLERRM);
    ROLLBACK;
    DBMS_OUTPUT.put_line('Transaction has been rolled back');
END;
/