21 JSON用のPL/SQLオブジェクト型の使用
JSON用のPL/SQLオブジェクト型を使用した例についていくつか説明します。
関連項目:
-
JSON_ARRAY_T
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。 -
JSON_ELEMENT_T
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。 -
JSON_OBJECT_T
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。 -
JSON_KEY_LIST
の詳細は、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください。
例21-1 インメモリーJSONオブジェクトの構成およびシリアライズ
この例では、関数parse
を使用して、name
という1つのフィールドを持つJSONオブジェクトを表すJSONデータの文字列を解析し、オブジェクト型JSON_ELEMENT_T
のインスタンスje
を作成します。このインスタンスは、オブジェクトを表すかどうかを確認するために、イントロスペクション・メソッド(述語)is_object()
を使用してテストされます。
インスタンスがオブジェクトを表す場合(述語がje
に対してTRUE
を戻す)、JSON_OBJECT_T
のインスタンスにキャストされて変数jo
に割り当てられます。次に、オブジェクト型JSON_OBJECT_T
のメソッドput()
を使用して、オブジェクト・フィールドprice
が値149.99
で追加されます。
最後に、JSON_ELEMENT_T
インスタンスのje
(JSON_OBJECT_T
インスタンスのjo
と同じインメモリーデータ)は、メソッドto_string()
を使用して文字列にシリアライズされ、この文字列がプロシージャDBMS_OUTPUT.put_line
を使用して出力されます。結果の出力には、更新されたオブジェクトが{"name":"Radio-controlled plane","price":149.99}
として表されます。
更新された一時オブジェクトje
は、ここで出力のためだけにシリアライズされますが、結果のテキストはデータベースには格納されません。場合によっては、サンプル・コードが実行された後に、オブジェクト型インスタンスje
およびjo
に割り当てられているメモリーは、ガベージ・コレクションによって回収されます。
DECLARE
je JSON_ELEMENT_T;
jo JSON_OBJECT_T;
BEGIN
je := JSON_ELEMENT_T.parse('{"name":"Radio controlled plane"}');
IF (je.is_Object) THEN
jo := treat(je AS JSON_OBJECT_T);
jo.put('price', 149.99);
END IF;
DBMS_OUTPUT.put_line(je.to_string);
END;
/
例21-2 メソッドGET_KEYS()を使用したオブジェクト・フィールドのリストの取得
PL/SQLメソッドget_keys()
が、PL/SQLオブジェクト型JSON_OBJECT_T
に対して定義されています。これにより、PL/SQLオブジェクト型JSON_KEY_LIST
のインスタンスが返されます。これは、VARCHAR2(4000)
のVARRAYです。VARRAYには指定されたJSON_OBJECT_T
インスタンスのフィールド名すべてが格納されています。
この例は、get_keys()
によって戻されるフィールドにわたって繰り返し処理し、これらのフィールドをPL/SQLオブジェクト型JSON_ARRAY_T
のインスタンスに追加します。次に、メソッドto_string()
を使用して、そのJSON配列をシリアライズして結果の文字列を出力します。
DECLARE
jo JSON_OBJECT_T;
ja JSON_ARRAY_T;
keys JSON_KEY_LIST;
keys_string VARCHAR2(100);
BEGIN
ja := new JSON_ARRAY_T;
jo := JSON_OBJECT_T.parse('{"name":"Beda",
"jobTitle":"codmonki",
"projects":["json", "xml"]}');
keys := jo.get_keys;
FOR i IN 1..keys.COUNT LOOP
ja.append(keys(i));
END LOOP;
keys_string := ja.to_string;
DBMS_OUTPUT.put_line(keys_string);
END;
/
出力は、["name","jobTitle","projects"]
のようになります。
例21-3 メソッドPUT()を使用したJSON文書の部分的な更新
この例では、表j_purchaseorder
のJSON列po_document
に含まれる発注書の文書をそれぞれ更新します。各文書内のJSON配列LineItems
にわたって繰り返し処理し(変数li_arr
)、明細項目オブジェクトごとに合計金額と数量を計算し(変数li_obj
)、メソッドput()
を使用してこれらの合計を新しいフィールドtotalQuantity
およびtotalPrice
の値としてli_obj
に追加します。これは、ユーザー定義の関数add_totals
を使用して行われます。
ここでのSELECT
文では、更新された文書の1つが選択されます。
CREATE OR REPLACE FUNCTION add_totals(purchaseOrder IN VARCHAR2) RETURN VARCHAR2 IS
po_obj JSON_OBJECT_T;
li_arr JSON_ARRAY_T;
li_item JSON_ELEMENT_T;
li_obj JSON_OBJECT_T;
unitPrice NUMBER;
quantity NUMBER;
totalPrice NUMBER := 0;
totalQuantity NUMBER := 0;
BEGIN
po_obj := JSON_OBJECT_T.parse(purchaseOrder);
li_arr := po_obj.get_Array('LineItems');
FOR i IN 0 .. li_arr.get_size - 1 LOOP
li_obj := JSON_OBJECT_T(li_arr.get(i));
quantity := li_obj.get_Number('Quantity');
unitPrice := li_obj.get_Object('Part').get_Number('UnitPrice');
totalPrice := totalPrice + (quantity * unitPrice);
totalQuantity := totalQuantity + quantity;
END LOOP;
po_obj.put('totalQuantity', totalQuantity);
po_obj.put('totalPrice', totalPrice);
RETURN po_obj.to_string;
END;
/
UPDATE j_purchaseorder SET (po_document) = add_totals(po_document);
SELECT po_document FROM j_purchaseorder po WHERE po.po_document.PONumber = 1600;
この更新された文書が選択されます。
{"PONumber": 1600,
"Reference": "ABULL-20140421",
"Requestor": "Alexis Bull",
"User": "ABULL",
"CostCenter": "A50",
"ShippingInstructions": {"name": "Alexis Bull",
"Address": {"street": "200 Sporting Green",
"city": "South San Francisco",
"state": "CA",
"zipCode": 99236,
"country": "United States of America"},
"Phone": [{"type": "Office", "number": "909-555-7307"},
{"type": "Mobile", "number": "415-555-1234"}]},
"Special Instructions": null,
"AllowPartialShipment": true,
"LineItems": [{"ItemNumber": 1,
"Part": {"Description": "One Magic Christmas",
"UnitPrice": 19.95,
"UPCCode": 13131092899},
"Quantity": 9.0},
{"ItemNumber": 2,
"Part": {"Description": "Lethal Weapon",
"UnitPrice": 19.95,
"UPCCode": 85391628927},
"Quantity": 5.0}],
"totalQuantity": 14,
"totalPrice": 279.3}