1 JavaScript用のOracle Database Multilingual Engineの概要

Oracle Databaseでは、PL/SQL、Java、Cなど、ユーザー定義のファンクションおよびストアド・プロシージャを記述するための豊富な言語がサポートされています。Oracle Database Multilingual Engine (MLE)を使用すると、開発者は、動的実行によってJavaScriptコードを実行することや、データベースに直接格納された永続的なMLEモジュールを使用してJavaScriptコードを実行することができます。

プログラミング言語を取り巻く状況は急速に進化し、JavaScriptのような最新の動的言語を使用することを選択する開発者が増加しています。シンプルな構文や、最新の言語機能のサポートに加えて、こうした言語の人気が高まった主要な要因の1つに、充実したモジュール・エコシステムの存在があります。開発者は、特定のタスクに適したモジュールを使用できるかどうかに基づいて、異なる言語を使用してプロジェクトの様々な部分を実装することを選択することがよくあります。

新しい言語が広く普及するかどうかは、多くの場合、コミュニティの関与にかかっています。言語がある程度以上一般化すると、通常、そのエコシステムが急速に拡大し始め、ますます多くの開発者を引き付けます。多くの場合、より広範な使用をサポートするために、豊富な機能、ライブラリおよび再利用可能なコード・モジュールが作成されます。

Oracle Databaseは、プログラミング言語の充実したエコシステムをサポートすることで知られています。Oracle Databaseへの最も一般的なサーバー側プログラム・インタフェースは、PL/SQLです。PL/SQLを使用すると、ビジネス・ロジックとデータをひとまとめにできるため、多くの場合、データについて統一された処理パターンが提供されることに加えて、効率が大幅に高まり、このことはどのようなクライアント・インタフェースを使用するかに関係ありません。MLEでは、PL/SQLを利用してJavaScriptモジュールを実装でき、データベースと直接対話するための新たな手段が提供されます。

関連項目:

Oracle Databaseでサポートされているプログラミング言語の詳細は、『Oracle Database開発ガイド』を参照してください。

トピック

マルチリンガル・エンジンの必要性

MLEを使用してデータベース内でデータを処理する利点について説明します。

開発者がSmart-DBアプローチを実装すると、アプリケーション・ロジックとデータが同じデータベース内に共存します。この戦略を適用すると、データベースは単なる永続性レイヤーまたは単純なREST APIではなく、本格的な処理エンジンとして使用されます。データを処理するためにデータベースを使用することで、セキュリティの強化、ネットワーク・ラウンドトリップの潜在的な排除、および参照整合性の使用によるデータ品質の向上という形で多くの利点が得られます。

データベースのオプティマイザにも、このアプローチによる利点があります。参照整合性制約を使用すると、操作しているデータの詳細を把握できます。また、セットベースのSQLを使用するとパフォーマンス上の利点を実現できます。多くの場合、データベース・サーバーはアプリケーションのフロントエンドを処理するマシンよりも強力であり、処理時間がさらに短縮されます。

Smart-DBアプローチでは、概念を最大限に活用するために、データベース・システムで提供されるプログラミング言語をよく理解している必要があります。唯一の他のオプションは、クライアント側のドライバを使用してデータベースからミドルウェア・システムまたはクライアント・マシンにデータを抽出し、処理することです。

処理されるデータの量が増え続けると、バッチ処理については特に、次の理由により、データベースからクライアントへの大量のデータの転送が問題となる可能性があります:

  • サーバー間でのデータベース情報の転送には時間がかかり、重大なネットワーク・オーバーヘッドが発生することがあります

  • 待機時間が大幅に増加することがよくあります。対話の多いアプリケーションについては特に、累積的影響が非常に顕著になる場合があります

  • 中間層またはクライアントで大量のデータを処理するには、これらの環境に大容量のDRAMとストレージを装備する必要があり、コストが増大します

  • マシン間のデータ転送は、クラウド環境では特に、固有のセキュリティ・リスクおよびデータ保護要件のために規制管理の対象となることがよくあります

データベース内でデータを処理することが、これらの問題の多くを軽減するための一般的な戦略となります。

Oracle Database Multilingual Engine (MLE)の導入に伴い、JavaScriptがデータベースに追加されました。JavaScriptはここに組み込まれることによってその言語の人気の高さが示され、その高度なエコシステムをサーバー側データベース開発に利用できるようになりました。

MLEでは、JavaScriptのエコシステムで提供されているイディオムやツールを使用できるとともに、Node Package Manager (NPM)などの一般的なリポジトリのモジュールをデータベース内に直接デプロイして使用できます。さらに、アプリケーション層間を移動できるため、様々なワークロードを処理するチームの柔軟性が向上します。JavaScriptの人材の大規模なプールは、既存および今後のプロジェクトの人員配置に役立ちます。

JavaScriptの概要

今日最も人気の高いプログラミング言語の1つであるJavaScriptは、JavaScriptエンジンを搭載したマシンで稼働します。開発者は、エンドツーエンドのアプリケーションの開発や高速実行のために、主にスクリプトの記述が容易であることからJavaScriptを好んで使用します。

JavaScript (JS)は、対話型Webページ向けのブラウザベースのソリューションとして誕生して以来、大きく進歩しました。フロントエンド開発において根強い人気を維持しながら、バックエンド開発にも使用できるようになりました。たとえば、Node.jsやDenoは、その領域で非常に一般的です。

根本的には、JavaScriptは、多くの最新のプログラミング・スタイルをサポートするインタプリタ型言語です。JavaScriptは、ECMA Internationalと呼ばれる管理機関によって継続的に拡張され、新しい標準が毎年リリースされています。

JavaScriptは、機能インタフェースとオブジェクト指向インタフェースの両方を備えています。JavaScriptはこのような名前であってもJavaとは大きく異なります。ただし、その構文は、人気の高い他の言語で知られている多くの構造を意図的に模倣しています。一般に認知された構文を採用することで、容易に学習できるようになっています。

非常に大規模で活発なコミュニティや、言語の豊富なライブラリ・セットなどのソフト面の要因によって、開発のための魅力的な選択肢となっています。

Oracle Database Multilingual Engine (MLE)の導入により、JavaScriptをOracle Database内で直接実行できます。データ集中型のアプリケーションでは、中間層からデータベースに処理ロジックを移動することでメリットを得ることができます。

関連項目:

JavaScriptの詳細は、Developer.mozilla.orgを参照してください

JavaScriptのマルチリンガル・エンジンの概要

MLEを使用すると、JavaScriptをOracle Database内で直接実行および格納できます。

MLEを使用すると、Oracle DatabaseのユーザーがJavaScriptで記述された次のものを実行できます。

  • ストアド・プロシージャ

  • ストアド・ファンクション

  • PL/SQLパッケージ・ネームスペースのコード

  • 匿名の動的コード・スニペット(DBMS_SQLと同様の方法)

MLEは、Linux x86-64の専用サーバー接続を使用してデータベースに接続するときにサポートされます。抽象データ型、PL/SQLコレクションとレコード型、およびREF CURSORはサポートされていません。また、初期化パラメータMAX_STRING_SIZEは、デフォルトから変更しないでください。

ノート:

共有サーバー接続およびデータベース常駐接続プール(DRCP)を使用している接続では、MLEを使用できません。

トピック

JavaScript実装の詳細

JavaScriptのMLE実装は、ECMAScript 2022に準拠しています。

このECMA標準に従って、MLEに見られるJavaScript実装は、純粋な実装として意識的に作成されます。ネイティブJavaScriptネットワークおよびファイルI/O操作は、セキュリティ上の理由からNode.jsおよびDenoと同じ方法ではサポートされていません。MLEではネットワークおよびファイルI/Oを使用できますが、UTL_HTTPUTL_FILEなどのPL/SQL APIを使用する必要があります。

WEB APIのFetchは、デフォルトではグローバル領域で使用できませんが、mle-js-fetchをインポートすることで有効にできます。

Windowオブジェクトなどのフロントエンド・コードで使用される共通オブジェクトを含め、ECMA標準に含まれていないオブジェクトもMLEでは使用できません。ただし、MLEでは、SQLへの簡単かつ効率的なアクセスが可能であり、それをデータの近くで実行できます。コンソール出力は、デフォルトではDBMS_OUTPUTに渡されますが、必要に応じてユーザー指定のCLOBにリダイレクトして格納できます。

ユーザーがMLEと対話するには、特定の権限が必要です。これらは、大まかに次のように分類できます:

  • MLEを使用し、JavaScriptコードを実行する権限

  • データベースでの動的JavaScriptの実行

  • JavaScriptモジュールの作成と、PL/SQLコードによるそれらの外部化

JavaScriptの使用に必要な十分な権限がない場合、データベース・エンジンはエラーをスローします。

データベースでのJavaScriptの起動

JavaScriptは、動的実行またはコール仕様(MLEモジュールまたはインラインJavaScriptファンクションを参照)を介して起動できます。

一般的に、サーバー側のJavaScriptコードは次の2つの方法で起動できます:

  • DBMS_MLEパッケージを介して動的に

  • JavaScriptモジュールでエクスポートされたファンクション(いわゆるMLEモジュール・コール)またはDDLで直接定義されたファンクションを参照するPL/SQLコードの使用

2つの方法のどちらを使用するかに関係なく、JavaScriptコードはすべて、実行コンテキストで実行されます。その目的は、JavaScriptコードの処理に関連するすべてのランタイム状態をカプセル化することです。MLE実行コンテキストは、JavaScriptのECMAScript実行コンテキストに対応しています。

関連項目:

ECMAScript実行コンテキストの詳細は、Ecma-international.orgを参照してください

動的実行の概要

匿名JavaScriptコード・スニペットは、DBMS_MLE PL/SQLパッケージを介して実行できます。

動的MLEスニペットを実行するには、プロシージャDBMS_MLE.eval()を使用します。このプロシージャは次の引数を使用します:

引数名 オプションかどうか
CONTEXT_HANDLE RAW(16) いいえ
LANGUAGE_ID VARCHAR2(64) いいえ
SOURCE CLOB いいえ
RESULT CLOB はい
SOURCE_NAME VARCHAR2 はい

引数SOURCE_NAMEは、本来であればランダムに命名されるJavaScriptコード・ブロックの名前を指定するために、オプションで使用します。

JavaScriptコードは、次のコードに示すように、PL/SQLにインラインで指定できます:

SET SERVEROUTPUT ON

DECLARE
    l_ctx DBMS_MLE.context_handle_t;
    l_jscode CLOB;
BEGIN
    l_ctx := DBMS_MLE.create_context;
    l_jscode := q'~
        console.log('Hello World, this is DBMS_MLE')
    ~';
    DBMS_MLE.eval(
        context_handle => l_ctx,
        language_id => 'JAVASCRIPT',
        source => l_jscode,
        source_name => 'My JS Snippet'
    );
END;
/

この例を実行すると、次のように出力されます:

Hello World, this is DBMS_MLE

前述のコードは、JavaScriptコードの動的な起動に関する次の概念を示しています:

  • 実行コンテキストは、明示的に作成する必要があります

  • JavaScriptコードは、キャラクタ・ラージ・オブジェクト(CLOB)またはVARCHAR2変数として指定します

  • コンテキストは、明示的に評価する必要があります

JavaScriptを動的に実行するときには、PL/SQLとJavaScriptの両方が存在します。指定されたコード・スニペットをネームスペースの外部で再使用することはできません。console.logへのコールの出力は、画面に出力するためにDBMS_OUTPUTに渡されます。

関連項目:

  • MLEを使用した動的実行の詳細は、「動的MLE実行の概要」を参照してください

  • プロシージャDBMS_MLE.eval()RESULT引数の詳細は、「最終実行の結果の戻し」を参照してください

MLEモジュール・コールの概要

データベース内に永続的に格納されるスキーマ・オブジェクトとしてJavaScriptモジュールを作成できます。

JavaScriptモジュールを定義したら、次に示すようにSQLおよびPL/SQLで使用できます:

CREATE OR REPLACE MLE MODULE helloWorld_module
LANGUAGE JAVASCRIPT AS
function helloWorld() {
    console.log('Hello World, this is a JS module');
}
export { helloWorld }
/

エクスポートされたJavaScriptファンクションを起動する前に、コール仕様を定義する必要があります。次のコード・スニペットは、PL/SQLでJavaScriptのhelloWorld()ファンクションのコール仕様を作成する方法を示しています:

CREATE OR REPLACE PROCEDURE helloWorld_proc
AS MLE MODULE helloWorld_module
SIGNATURE 'helloWorld()';
/

MLEモジュール・コールと呼ばれるコール仕様によって、JavaScriptファンクションhelloWorld()が公開されます。その後、他のPL/SQLプロシージャと同様にそれを使用できます。次のスニペットは、このファンクションを起動する方法とともにその結果を示しています:

SET SERVEROUTPUT ON

BEGIN
    helloWorld_proc;
END;
/

結果:

Hello World, this is a JS module

提供されたコードに示されているカスタム作成のJavaScriptモジュールに加えて、サードパーティのJavaScriptモジュールをデータベースにロードできます。業界のベスト・プラクティスに従ってサードパーティ・コードのセキュリティ・スクリーニングを実行することをお薦めします。

関連項目:

  • MLEモジュールおよび環境の詳細は、「MLE JavaScriptモジュールおよび環境」を参照してください

  • MLEのセキュリティ機能および推奨事項の詳細は、「MLEのセキュリティ」を参照してください

MLE実行コンテキストについて

MLE実行コンテキストは、分離されたスタンドアロンのランタイム環境であり、JavaScriptコードの実行に関連付けられたすべてのランタイム状態を含むように設計されています。ランタイム状態には、グローバル変数と、言語環境の状態が含まれます。

ノート:

MLE実行コンテキストは、JavaScriptのECMAScript実行コンテキストに対応しています。
MLEでは、次の2つの異なるシナリオで実行コンテキストが使用されます:
  • 動的MLEコンテキストを明示的に作成して使用できる、動的MLE実行

  • MLEモジュールによってエクスポートされたファンクションへのSQLおよびPL/SQLからのコール

動的実行

動的MLEコンテキストのプロパティは、実行コンテキストが作成された時点で使用されている環境によって決定されます。それぞれの動的MLEスニペットに使用される実行コンテキストを明示的に制御でき、それぞれの実行コンテキストで単一のユーザーの代理としてコードが実行されます。

1つのセッション内で作成できる動的MLE実行コンテキストの数や、異なるコード・スニペット間でそれらを共有する方法に制限はありません。JavaScriptのコード・スニペットは、同じ実行コンテキストで実行されている他のコード・スニペットとすべてのグローバル変数を共有します。

MLEモジュール

SQLまたはPL/SQLからのMLEモジュール・コールのコンテキストは、オンデマンドで暗黙的に作成されます。ここでは、コンテキストの作成時点でコール仕様で参照されているMLE環境によってプロパティが決定されます。環境を使用して、言語オプションを指定したり、MLEモジュールをインポート可能にしたりできます。

MLEモジュールは、他のモジュールや動的MLEスニペットと実行コンテキストを共有することはありません。また、同じMLEモジュールのコードが異なるユーザーの代理として実行されるときには、別個の実行コンテキストが使用されます。MLEは、MLEモジュールと環境の組合せごとに専用の実行コンテキストを作成します。異なるモジュールまたは異なる環境を指定する2つのコール仕様は、別個のモジュール・コンテキストで実行されます。

関連項目:

  • MLE環境の詳細は、「MLEモジュールの環境の指定」を参照してください

  • 実行コンテキストを使用してランタイム状態の分離を強制する方法の詳細は、「実行コンテキスト」を参照してください

JavaScriptコードのデバッグの概要

MLEを使用すると、プログラムの実行中にランタイム状態を便利かつ効率的に収集することで、JavaScriptコードをデバッグできます。

MLEコードの実行が終了したら、収集されたデバッグ・データを使用してプログラムの動作を分析し、バグを検出して修正できます。この形式のデバッグは、実行後デバッグと呼ばれます。

実行後デバッグ・オプションでは、デバッグポイントを使用してコードを計測できます。デバッグポイントを使用すると、個々の変数の値や実行スナップショットなど、プログラムの状態を条件付きまたは無条件でログに記録できます。デバッグポイントは、アプリケーション・コードとは別のJSONドキュメントとして指定します。デバッグポイントを起動するために、アプリケーション・コードを変更する必要はありません。

アクティブ化すると、デバッグ仕様に従ってデバッグ情報が収集され、これをフェッチすると、標準的な形式を生かして広範なツールで分析できます。

関連項目:

MLEを使用した実行後のデバッグの詳細は、「MLE JavaScriptモジュールの実行後のデバッグ」を参照してください