MLEモジュール・コール用のJavaScriptコードの準備

MLEのJavaScriptモジュールは、モジュール用のECMAScript 6標準に従います。MLEモジュールのユーザーが使用すると予想されるファンクションと変数をエクスポートする必要があります。

エクスポートされない変数およびファンクションは、モジュール内でプライベートとみなされます。例3-3は、MLE JavaScriptモジュールでのパブリック・ファンクションとプライベート・ファンクションの両方の使用を示しています。

ECMAScriptモジュールは、インポート文または動的インポート・コールを使用して、他のECMAScriptモジュールをインポートできます。この機能は、MLEにもあります。MLE環境では、MLEモジュールを補完するメタデータが提供されます。

MLEのコンソール出力は、コンソール・オブジェクトを使用することで容易になることに注意してください。デフォルトでは、console.log()に書き込まれた内容はすべてDBMS_OUTPUTにルーティングされ、画面に表示されます。

例3-1のようなJavaScriptコードは、コール仕様なしでSQLまたはPL/SQLからアクセスすることはできません。コール仕様は、PL/SQLプログラム・ユニット(ファンクション、プロシージャまたはパッケージ)と考えることができます。ここで、例3-2に示すように、そのPL/SQL本体がJavaScriptモジュールおよびファンクションへの参照に置き換えられます。コール仕様の詳細は、「MLE JavaScriptファンクション」を参照してください。

例3-2 パブリック・ファンクションのコール仕様の作成

この例では、例3-1で作成したモジュールpo_moduleを使用します。po_moduleでエクスポートされる唯一のファンクションであるorderValue()のコール仕様は、次のように記述できます:


CREATE OR REPLACE FUNCTION order_value(
    p_line_items JSON
) RETURN NUMBER AS
MLE MODULE po_module
SIGNATURE 'orderValue';
/

ファンクションを作成すると、特定の購買オーダーの値を計算できます:


SELECT
    po.po_document.PONumber,
    order_value(po.po_document.LineItems[*]) order_value
FROM
    j_purchaseorder po;

結果:


PONUMBER   ORDER_VALUE
---------- -----------
1600             279.3
672              359.5

例3-3 JavaScriptモジュールのパブリック・ファンクションとプライベート・ファンクション

パブリック(エクスポート済)ファンクションに加えて、モジュールにプライベートなファンクションを追加できます。この例では、値の計算はmap()ファンクションから取り出され、別のファンクションに移動されます(リファクタリング)。

次のコードの最初のファンクションlineItemValue()はプライベートとみなされ、2番目のファンクションorderValue()はパブリックです。exportキーワードは、このコード・リストの最後に指定されていますが、例3-1に示すように、変数およびファンクションの接頭辞として出現することもあります。どちらのバリエーションも有効なJavaScript構文です。


CREATE OR REPLACE MLE MODULE po_module LANGUAGE JAVASCRIPT AS

/**
* calculate the value of a given line item. Factored out of the public 
* function to allow for currency conversions in a later step
* @param {number} unitPrice - the price of a single article
* @param {number} quantity - the quantity of articles ordered
* @returns {number} the monetary value of the line item
*/
function lineItemValue(unitPrice, quantity) {
    return unitPrice * quantity;
}

/**
* get the value of all line items in an order
* @param {array} lineItems - all the line items in a purchase order
* @returns {number} the total value of all line items in a purchase order
*/
function orderValue(lineItems) {
    
    return lineItems
                .map( x => lineItemValue(x.Part.UnitPrice, x.Quantity) )
                .reduce( 
                    (accumulator, currentValue) => accumulator + currentValue, 0 
                );
}

export { orderValue }
/