動的実行ワークフロー
動的MLE実行に必要なステップについて説明します。
ユーザーがDBMS_MLE
を使用してJavaScriptコードを作成および実行できるようにするには、複数の権限を付与する必要があります。必要な権限の詳細は、「MLEでのJavaScriptの操作に必要なシステム権限およびオブジェクト権限」を参照してください。
DBMS_MLE
を使用したJavaScriptコードの実行ワークフローは次のとおりです:
- 実行コンテキストを作成します
VARCHAR2
変数またはCLOB変数を使用してJavaScriptコードを指定します- 必要に応じてPL/SQLエンジンとMLEエンジンの間で変数を渡して、コードを実行します
- 実行コンテキストのクローズ
コードと同様に、予期しない状況に対処することが業界のベスト・プラクティスとされています。これは、標準のJavaScript例外処理機能を使用してJavaScriptコード自体で行うか、またはPL/SQLで行うことができます。
トピック
- インラインでのJavaScriptコードの指定
引用演算子の使用は、動的実行の実行時にJavaScriptコードをインラインで提供するために推奨される方法です。 - ファイルからのJavaScriptコードのロード
BFILE
演算子を使用してCLOBで読み取る方法について説明します。
親トピック: 動的MLE実行の概要
インラインでのJavaScriptコードの指定
引用演算子の使用は、動的実行の実行時にJavaScriptコードをインラインで提供するために推奨される方法です。
引用演算子(通常はq-quote演算子と呼ばれる)は、JavaScriptコードをPL/SQLブロック内に直接埋め込むことでロードするために使用できるオプションの1つです。PL/SQLコードにインラインでJavaScriptコードを指定する場合、可能なときには常にこの代替の引用演算子を使用することをお薦めします。
q-quote演算子は動的実行の推奨メソッドですが、インライン・コール仕様を使用するときは、{{...}}
などのデリミタを使用してJavaScriptコードを囲むことに注意してください。これらのデリミタ・オプションについてさらに学習するには、「インラインMLEコール仕様の作成」を参照してください。
例4-1 q-quote演算子を使用した、PL/SQLへのJavaScriptコードのインラインでの指定
DECLARE
l_ctx dbms_mle.context_handle_t;
l_snippet CLOB;
BEGIN
l_ctx := dbms_mle.create_context();
l_snippet := q'~
// the q-quote operator allows for much more readable code
console.log(`The use of the q-quote operator`);
console.log(`greatly simplifies provision of code inline`);
~';
dbms_mle.eval(l_ctx, 'JAVASCRIPT', l_snippet);
dbms_mle.drop_context(l_ctx);
EXCEPTION
WHEN OTHERS THEN
dbms_mle.drop_context(l_ctx);
RAISE;
END;
/
結果:
The use of the q-quote operator
greatly simplifies provision of code inline
親トピック: 動的実行ワークフロー
ファイルからのJavaScriptコードのロード
BFILE
演算子を使用してCLOBで読み取る方法について説明します。
linterを使用してコード分析を実行する場合、PL/SQLにインラインでJavaScriptコードを指定することは、動的実行には最適な選択肢ではない可能性があります。JavaScriptコードを提供するもう1つの方法は、BFILE
演算子を使用してCLOBを読み取ることです。この方法では、PL/SQLとJavaScriptコードを明確に分離できます。
関連項目:
ラージ・オブジェクトの詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください
例4-2 DBMS_LOB.LOADCLOBFROMFILE()を使用した、BFILEからのJavaScriptコードのロード
次の例は、BFILE
およびDBMS_LOB.LOADCLOBFROMFILE()
の使用方法を示しています。
この例では、SRC_CODE_DIR
という名前のディレクトリへの読取りアクセス権があることを想定しています。ソース・コード・ファイルhello_source.js
はそのディレクトリにあります。内容は次のとおりです。
console.log('hello from hello_source');
DECLARE
l_ctx dbms_mle.context_handle_t;
l_js CLOB;
l_srcode_file BFILE;
l_dest_offset INTEGER := 1;
l_src_offset INTEGER := 1;
l_csid INTEGER := dbms_lob.default_csid;
l_lang_context INTEGER := dbms_lob.default_lang_ctx;
l_warn INTEGER := 0;
BEGIN
l_ctx := dbms_mle.create_context();
dbms_lob.createtemporary(lob_loc => l_js, cache => false);
l_srcode_file := bfilename('SRC_CODE_DIR', 'hello_source.js');
IF ( dbms_lob.fileexists(file_loc => l_srcode_file) = 1 ) THEN
dbms_lob.fileopen(file_loc => l_srcode_file);
dbms_lob.loadclobfromfile(
dest_lob => l_js,
src_bfile => l_srcode_file,
amount => dbms_lob.getlength(l_srcode_file),
dest_offset => l_dest_offset,
src_offset => l_src_offset,
bfile_csid => l_csid,
lang_context => l_lang_context,
warning => l_warn
);
IF l_warn = dbms_lob.warn_inconvertible_char THEN
raise_application_error(
-20001,
'the input file contained inconvertible characters'
);
END IF;
dbms_lob.fileclose(l_srcode_file);
dbms_mle.eval(
context_handle => l_ctx,
language_id => 'JAVASCRIPT',
source => l_js
);
dbms_mle.drop_context(l_ctx);
ELSE
raise_application_error(
-20001,
'The input file does not exist'
);
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_mle.drop_context(l_ctx);
RAISE;
END;
/
結果:
hello from hello_source
例4-3 DBMS_MLEからのMLEモジュールの参照によるBFILEからのJavaScriptコードのロード
例4-2に示すように、JavaScriptモジュールのコードはファイルに再度格納されます。この例では、SRC_CODE_DIR
という名前のディレクトリに対する読取りアクセス権があり、ファイル名がgreeting_source.js
であると想定しています。
export function greeting(){
return 'hello from greeting_source';
}
この例では、先行するファイルの内容を使用して、BFILE
からMLEモジュールを作成することから始めます。モジュールをDBMS_MLE
で使用するには、まず環境を作成し、JavaScriptコードの動的部分でモジュールを参照できるようにする必要があります。
動的MLE実行では、ECMAScriptのimport
キーワードは使用できません。かわりに、この例に示すasync/awaitインタフェースを使用してMLEモジュールを動的にインポートする必要があります。
CREATE OR REPLACE MLE MODULE greet_mod
LANGUAGE JAVASCRIPT
USING BFILE(SRC_CODE_DIR, 'greeting_source.js');
/
CREATE OR REPLACE MLE ENV greet_mod_env
imports ('greet_mod' module greet_mod);
DECLARE
l_ctx dbms_mle.context_handle_t;
l_snippet CLOB;
BEGIN
l_ctx := dbms_mle.create_context(
environment => 'GREET_MOD_ENV'
);
l_snippet := q'~
(async () => {
let { greeting } = await import('greet_mod');
const message = greeting();
console.log(message);
})();
~';
dbms_mle.eval(
l_ctx,
'JAVASCRIPT',
l_snippet
);
dbms_mle.drop_context(l_ctx);
EXCEPTION
WHEN OTHERS THEN
dbms_mle.drop_context(l_ctx);
RAISE;
END;
/
結果:
hello from greeting_source
関連項目:
MLEモジュールでBFILE
を使用してJavaScriptコードをロードする方法の詳細は、「MLEにJavaScriptコードを指定するための追加オプション」を参照してください
親トピック: 動的実行ワークフロー