2023年4月25日火曜日

動的アクションのイベント有効範囲を確認する

 Oracle APEXの動的アクションイベント有効範囲という設定があります。このイベント有効範囲として、静的動的1回のどれかを選ぶことができます。

簡単なアプリケーションを作成し、このプロパティイベント有効範囲の使い方を確認します。


確認アプリケーションの作成


以下のページを作成し、それぞれイベント有効範囲が異なる動的アクションを作成します。

ボタン、ページ・アイテム、動的コンテンツのリージョンを作成します。


ボタンREFRESHをクリックすると、リージョンTESTをリフレッシュします。ボタン動作アクションとして動的アクションで定義を指定します。


動的アクションのタイミングイベントクリック選択タイプボタンボタンREFRESHになります。


実行するTRUEアクションとしてリフレッシュを選択します。影響を受ける要素選択タイプリージョンリージョンTESTを指定します。


ページ・アイテムP1_STATUSを作成します。タイプテキスト・フィールドです。このページ・アイテムは、動的アクションのイベント有効範囲の違いを確認するために使用します。

ページ番号1イベント有効範囲静的のケース、ページ番号2動的のケース、ページ番号31回のケースを実装します。そのため、作成するページ・アイテムは、ページ番号に従ってP1_STATUSP2_STATUSP3_STATUSとなります。


タイプ動的コンテンツリージョンを作成します。

ソースCLOBを返すPL/SQLファンクション本体として、以下を記述します。


クラスdummyclassが設定されたDIV要素に対して動的アクションを作成します。この要素にマウスが乗った時テキスト・コンテンツをページ・アイテムPn_STATUSにコピーします。

詳細静的IDとしてtestを設定します。



イベント有効範囲が静的のケース



動的コンテンツに含まれるDIV要素動的アクションを作成するため、動的アクション・ビューより動的アクションを作成します。

実行イベント有効範囲として静的を選択します。

タイミングイベントマウス・エンター選択タイプjQueryセレクタjQueryセレクタとして#test .dummyclassを指定します。

リージョンTESTに含まれるDIV要素(classにdummyclassを含む)にマウスが乗ると、TRUEアクションが実行されます。


実行するTRUEアクションとしてJavaScriptコードの実行を選択し、設定コードとして以下を記述します。

console.log(this.triggeringElement.textContent);
apex.items.P1_STATUS.setValue(this.triggeringElement.textContent);

初期化時に実行オフにします。


マウスが離れたときに、ページ・アイテムをクリアする動的アクションも作成します。

タイミングイベントマウス・リーブを選択します。選択タイプjQueryセレクタは、マウス・エンターと同じ設定にします。


TRUEアクションとしてクリアを選択します。影響を受ける要素選択タイプアイテムアイテムとしてP1_STATUSを選択します。

実行初期化時に実行オフにします。


リージョンTESTの属性にあるパフォーマンスの遅延ロードは、オフであることが必須です。


イベント有効範囲静的の場合、動的アクションが設定されたHTML要素が更新されるとイベントが処理されなくなります。ページ全体の再ロードを伴わない更新は、一般にリージョンリフレッシュとして実装されています。遅延ロードオンの場合は、ページのロード後にリージョンのリフレッシュを実行するといった動作になるため、イベントが処理されなくなります。

イベント有効範囲が静的の場合は、以下のような動作になります。

ページ・ロード直後はDIV要素にマウスを乗せると動的アクションが呼び出され、ページ・アイテムP1_STATUSに文字列がコピーされます。その後、ボタンRefreshをクリックし、リージョンTESTをリフレッシュすると、動的アクションは(ページを再ロードするまで)呼び出されなくなります。



イベント有効範囲が動的のケース



実行イベント有効範囲動的にします。静的コンテナ(jQueryセレクタ)として#testを設定します。#testで指定されるリージョンTESTの内容は、リフレッシュを実行することにより書き換えられます。しかし、リージョンTESTの枠は変わらないため、静的コンテナとして指定できます。

タイミングイベントマウス・エンター選択タイプとしてjQueryセレクタjQueryセレクタとして.dummyclassを指定します。


動的アクションMouse Leaveイベントマウス・リーブを選択する以外は、マウス・エンターと同じ設定にします。


イベント有効範囲動的としている場合は、リージョンTESTの遅延ロードオンにできます。


イベント有効範囲を動的にした場合の動作です。

リージョンのリフレッシュを行った後も動的アクションが呼び出されています。



イベント有効範囲が1回のケース



イベント有効範囲1回は静的と近いですが、動的アクションが1回呼び出されると、それ以降は(ページが再ロードされるまで)呼び出されません。

実行イベント有効範囲1回タイミング選択タイプjQueryセレクタjQueryセレクタとして#test .dummyclassを設定します。リージョンTESTの遅延ロードオフにします。


イベント有効範囲を1回にした場合の動作です。

ページ・ロード直後に1回だけ動的アクションが呼び出されますが、それ以降は呼び出されなくなります。また、呼び出されない状況はリージョンのリフレッシュを行っても変わりません。


動的アクションのイベント有効範囲の説明は以上になります。

今回の確認作業で使用したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/dynamic-actions-event-scope-test.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

2023年4月21日金曜日

Oracle APEX 23.1のプッシュ通知を使ってみる

apex.oracle.comのAPEXが23.1のプレリリース版にアップグレードされました。APEX 23.1にて提供される新機能のひとつである、プッシュ通知を確認してみます。

いち早く動作を確認した方がYouTubeに動画をポストしていたので、その内容を参考にしました。

Push Notifications - Oracle APEX 23.1 New Features
https://www.youtube.com/watch?v=u_re_3cxz3U

apex.oracle.comのワークスペースを使用します。

アプリケーション作成ウィザードを起動し、新規にアプリケーションを作成します。

アプリケーション・アイコン名前はプッシュ通知の表示に含まれます。後からでも変更できますが、通知に表示されることを意識して設定することをお勧めします。

機能に含まれるプログレッシブWebアプリケーションのインストールプッシュ通知チェックを入れます。

以上で、アプリケーションの作成を実行します。


アプリケーションが作成されます。機能としてプッシュ通知を含めたため、ページ番号20020として、プッシュ通知の設定を行うページが作成されています。


アプリケーションを実行します。

まだ何もアプリケーションには実装していません。

ナビゲーション・バーの一番右にユーザー名のメニューがあります。そのメニューから設定を開きます。


画面右よりドロワーが開きます。プッシュ通知をクリックすると設定画面が開きます。


このデバイスでプッシュ通知を有効にするチェックを入れると、プッシュ通知が有効化されます。画面上に説明されていますが、通知はデバイスごとに有効にする必要があり、また、ブラウザやデバイスで通知を許可する必要があります。


設定に戻ると、プッシュ通知オンに変わっていることが確認できます。


ホーム・ページにプッシュ通知を送信する画面を作成します。作成した画面は以下のようになります。


通知先を指定するページ・アイテムを作成します。

識別名前P1_PUSH_TOタイプ選択リストとします。ラベルPush Toとしています。LOVタイプSQL問合せを選択し、SQL問合せとして以下を記述します。

select user_name d, user_name r from APEX_WORKSPACE_APEX_USERS where workspace_id = :WORKSPACE_ID

ワークスペースに作成されているユーザーから、通知の宛先を選択します。


通知のタイトルを記述するページ・アイテムを作成します。

識別名前P1_TITLEタイプテキスト・フィールドラベルTitleとします。


同様に通知の本文を指定するページ・アイテムを作成します。

識別名前P1_MESSAGEタイプテキスト・フィールドラベルMessageとします。


プッシュ通知を実行するボタンを作成します。

識別ボタン名NOTIFYラベルNotifyとします。動作アクションはデフォルトのページの送信です。


プロセス・ビューを開き、プッシュ通知を行うプロセスを作成します。

識別名前プッシュ通知とします。タイププッシュ通知の送信を選択します。

設定宛先&P1_PUSH_TO.タイトル&P1_TITLE.本文&P1_MESSAGE.とします。リンク・ターゲットに、同じアプリケーションのページ番号を指定します。

ボタンNotifyをクリックした時に実行されるように、サーバー側の条件ボタン押下時としてNOTIFYを選択します。


アプリケーションを実行し、アプリケーションのインストールを実施します。


アプリケーションのインストールができたら、プッシュ通知の設定を再度確認します。


Push ToTitleMessageを指定して、Notifyをクリックして通知を実行します。


Apple iOSのデバイスに作成したアプリをインストールし、通知を確認してみました。PWAのプッシュ通知はiOS/iPadOS 16.4以降のSafariでサポートされます。


プッシュ通知の実装の確認は以上です。

動かないと思ったら?


通知のサブスクリプションが登録されているかどうか、ビューAPEX_APPL_PUSH_SUBSCRIPTIONSを検索して確認します。

select * from APEX_APPL_PUSH_SUBSCRIPTIONS;


Google Chromeから通知を設定した場合はSUBSCRIPTION_INTERFACEendpointとしてfcm.googleapis.com、Appleのデバイスではweb.push.apple.comを呼び出すように設定されています。

一見してサブスクリプションが登録されているように見えても、プッシュ通知をONにしたままPWAとしてインストールしたアプリケーションを削除した場合など、無効なサブスクリプションが残っていることがあります。通知を受けるアプリケーションでプッシュ通知のオン・オフを行い、サブスクリプションが正しく登録されていることを確認します。

プッシュ通知は、APEXのインスタンスからfcm.googleapis.com、web.push.apple.comへHTTPのリクエストを発行することによって実施されています。

発行されたHTTPリクエストを確認することで、APEXからプッシュ通知が行われたかどうか確認できます。発行されたHTTPリクエストは、APEX_WEBSERVICE_LOGから確認します。

select id, url, http_method, status_code, to_char(request_date, 'RR/MM/DD HH24:MI:SS') request_date from apex_webservice_log order by request_date desc


apex.oracle.comでは、2分毎に通知を処理しているようです。そのため、プッシュ通知を実行して受信するまでに、最大で2分の遅延が発生します。

プッシュ通知の要求が成功していれば、HTTPのステータス・コードは200番台の値になります。

HTTPリクエストが成功しているにもかかわらず、プッシュ通知が受信できない場合、まずはデバイス側で通知が許可されているか確認します。

Google Chromeの場合は設定プライバシーとセキュリティサイトの設定に含まれる、apex.oracle.com通知の設定を確認します。


iOSの場合は設定アプリの通知より、プッシュ通知(ホーム・ページにインストールしたアプリの名前です)を探します。



プッシュ通知の資格証明


プッシュ通知を組み込んでいるアプリケーションの、共有コンポーネントプログレッシブWebアプリケーションプッシュ通知のセクションは以下のようになっています。

アプリケーションにプッシュ通知を組み込む際に、Web資格証明が自動的に生成されてプッシュ通知資格証明として設定されています。


ワークスペース・ユーティリティWeb資格証明からも、自動的に作成されたWeb資格証明を確認できます。


このアプリケーションをエクスポートし、再度インポートした際には、この資格証明がWeb資格証明として存在しているかどうか、存在していない場合は資格証明の再生成の実施を検討する必要があります。



APIによる通知


作成したアプリケーションプッシュ通知コピーを作ります。

タスクこのアプリケーションをコピーを実行します。


新規アプリケーション名プッシュ通知 - APIとします。

へ進みます。


アプリケーションのコピーを実行します。


アプリケーションのコピーが作成されます。

ホーム・ページページ・デザイナで開き、プロセスプッシュ通知を選択します。

識別タイプコードを実行に変更し、ソースPL/SQLコードとして以下を記述します。p_application_idには、コピー元であるアプリケーションのIDを指定します。
begin
    apex_pwa.send_push_notification(
        p_application_id => [コピー元のアプリケーションID]
        ,p_user_name => :P1_PUSH_TO
        ,p_title => :P1_TITLE
        ,p_body => :P1_MESSAGE
    );
end;

以上で、APIによるプッシュ通知ができるようになりました。プロセス・タイププッシュ通知の送信の場合、通知の送信先は同じアプリケーションでしたが、APIの場合は異なるアプリケーションに通知できます。

APIによるプッシュ通知を送信するアプリケーションは、プログレッシブWebアプリケーション無効でも、通知を送信できます。



Oracle APEX 23.1の新機能、プッシュ通知の紹介は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。

2023年4月20日木曜日

apex.oracle.comがOracle APEX 23.1のプレリリース版にアップグレードされました

 まだ翻訳されていないため、日本語の環境からapex.oracle.comにアクセスしても、Oracle APEX 23.1の情報が見つかりません。

Oracle APEX 23.1の新機能ガイドのURLは以下になります。

https://apex.oracle.com/en/platform/features/whats-new-231/

新しく追加された機能として、以下があります。

テンプレート・コンポーネント


今までのクラシック・レポートは静的なHTMLをテンプレートとして、サーバー側で完全なHTMLを生成していました。静的なテンプレートの代わりにテンプレート・コンポーネントを導入し、テンプレート・ディレクティブの記述によりクライアント側で完全なHTMLを生成します。

テンプレート・コンポーネントはプラグインという形で、独立してエクスポートできます。一度、テンプレート・ディレクティブで記述したUIを容易に他のアプリケーションに導入できるようです。

クラシック・レポートを置き換えるもので、カード・リージョンについても(少なくても行レイアウトについては)置き換える対象となるでしょう。

Philipp Hartenfellerさんのブログ記事で詳しく紹介されています。

PWAのプッシュ通知


Oracle APEXだけでプッシュ通知ができるようになりました。プッシュ通知を行うプロセス・タイプおよびAPIが提供されているようです。GoogleのFirebaseを使ったりプッシュ通知を転送するサーバーが不要になりました。

以下の記事で紹介している作業は不要になります。
Firebaseを使ってAPEXアプリにプッシュ通知を実装する(1) - Firebaseの設定
Firebaseを使ってAPEXアプリにプッシュ通知を実装する(2) - Node.jsの準備
Firebaseを使ってAPEXアプリにプッシュ通知を実装する(3) - APEXアプリの作成

開発者であるVincent Morneauさんが、この機能についてツイートしています。



オブジェクト・ブラウザの刷新


表やビューを選択リストで選んで一覧する形式から、ツリーで表示するように変わりました。全体的に使いやすくなりました。


ページ・プロセスの拡張


プロセスをバックグラウンドで実行できるようになりました。時間がかかる処理を、DBMS_SCHEDULERを呼び出して、自力でジョブとしてスケジュールする必要がなくなりました。またバックグラウンドの処理の進捗を確認するためのAPIも提供されているようです。

以下の記事で紹介している作業の一部は不要になるでしょう。
APEX_DATA_LOADINGを使ってデータをロードする


RESTデータ・ソースの拡張


APEX 22.2で実装されたAPI呼び出しが、ローカルのプロシージャやファンクション以外にREST APIも呼び出せるように拡張されました。

また、REST APIの検出に呼び出し時のレスポンスだけではなく、Swagger/OpenAPIも使えるようになったとのことです。

大項目以外の新機能で気になったもの


Application Continuity - ページ・アイテムへの値の代入時にトランザクションがコミットされる(こちらの記事で解説)動作を制御可能にした模様です。ページ処理の終了時にコミットすることで、それまでに例外が発生した場合、全体がロールバックされます。いわゆる冪等性(idempotency)の確保を容易にしています。

Export and Import in Theme Roller - テーマ・ローラーからテーマのエクスポートとインポートができるようになった、とのことです。

Adopted TinyMCE - リッチ・テキスト・エディタのコンポーネントとして今まではCKEditorを使用していました。これがTinyMCEに置き換わりました。

以前に書いたCKEditorに関係する記事は無効になります。
CKEditor5でのリンク属性にtarget, relを付加する
CKEditor5による画像アップロードを実装する(1) - 準備
CKEditor5による画像アップロードを実装する(2) - REST APIの作成
CKEditor5による画像アップロードを実装する(3) - 完成
CKEditor5による画像アップロードを実装する(4) - 画像をオブジェクト・ストレージに保存する
CKEditor5による画像アップロードを実装する(5) - 動的コンテンツを使う
CKEditor5のInline editorを使ってみる
CKEditor5のmention機能を実装してみる
リッチ・テキスト・エディタでHTMLを読み込むだけで元のHTMLが変更される

2023年4月20日よりAPEX Office HoursでAPEX 23.1関連のセッションが始まります。

Part 1: What's new in Oracle APEX 23.1 (日本時間の4/20 23:00)
Part 2: What's new in Oracle APEX 23.1 (日本時間の4/27 23:00)
Part 3: What's new in Oracle APEX 23.1 (日本時間の5/4 23:00)
Part 4: What's new in Oracle APEX 23.1 (日本時間の5/11 23:00)

これらのセッションで新機能について詳しく解説されるでしょう。

2023年4月14日金曜日

カレンダを月曜日から始める

標準のカレンダを月曜日から始める方法を紹介します。Oracle APEXのギャラリに含まれているサンプル・カレンダを使って確認します。

デフォルトではカレンダは日曜日から始まります。

ページ・デザイナを開いて、カレンダ・リージョン属性を確認します。一般にリージョン固有の設定(この場合はカレンダ)は、プロパティ・エディタ属性に含まれます。

開始する曜日の指定は、設定には含まれていません。また、詳細初期化JavaScriptファンクションヘルプにも、そのような指定は含まれていません。

Oracle APEXのカレンダ・リージョンは、実際はFullCalendarです。そのため、FullCalendarに機能として含まれていれば、Oracle APEXから(設定やヘルプに含まれていなくても)利用することができます。

コンポーネントのバージョンに注意が必要です。Oracle APEXにバンドルされているJavaScriptコンポーネントは、必ずしも最新ではありません。バージョンはリリース・ノートに記載されています。FullCalendarは5.11.2がバンドルされています。FullCalendar自体の最新バージョンは6.1.5(2023年4月14日現在)です。

FullCalendarのドキュメントを確認すると、firstDayというプロパティが見つかりました。

https://fullcalendar.io/docs/v5/firstDay


fistDayを1とするとカレンダが月曜日から開始されます。(デフォルトは0 - 日曜日)

以下のコードを詳細初期化JavaScriptファンクションに記述します。
function (p) {
    p.firstDay = 1;
}

ページを実行すると、カレンダが月曜日から始まっていることが確認できます。


カレンダ以外でも、3rdパーティのJavaScriptコンポーネントを使って実装されているリージョンやページ・アイテムがあります。チャートであればOracle JET、リッチ・テキスト・エディタであればCKEditor5、マップ・リージョンであればMapLibreのドキュメントを参照することにより、それらのコンポーネントに実装されている機能をさらに活用することができます。

以上です。

Oracle APEXのアプリケーション作成の参考になれば幸いです。

2023年4月13日木曜日

Gistに保存したコードからMLE JavaScriptモジュールを作成する

以前の記事DB 23cのMLEでJavaScriptモジュールを作成するにて、以下のDDLによりDB 23cのMLE JavaScriptモジュールfactorial_modを作成しています。

CREATE OR REPLACE MLE MODULE factorial_mod LANGUAGE JAVASCRIPT AS

export function factorial(num) {
    if(num < 0) {
        return -1;
    } else if (num == 0) {
        return 1;
    } else {
        return(num * factorial(num-1));
    }
}
/
このJavaScriptのコードをDDL中に記述する代わりに、Gistに作成したスニペットを使用します。


例えば以下のURLより、Gistのスニペットを取得できます。

https://gist.githubusercontent.com/ujnak/1808026f3728baedc908b5baf8ac4b99/raw/4dbf9898971f8b696eb83d86f33f2246ecb6d40d/factorial_mod.js

ホストgist.githubusercontent.comへRESTコールアウトができない場合は、以下のコードをSYSで実行して、コールアウトを許可します。
begin
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host => 'gist.githubusercontent.com',
    ace => xs$ace_type(
        privilege_list => xs$name_list('connect','resolve'),
        principal_name => 'APEX_220200',
        principal_type => xs_acl.ptype_db));
  commit; 
end;
/
ネットワークACLの設定については、以下の記事で解説しています。

Autonomous DatabaseのAPEXでUTL_HTTPを使用する

以上の準備が済んだところで、JavaScriptのモジュールを作成します。以下のDDLを実行します。(23cからfrom dualが不要になりました。このコードではfrom dualを省いています。)


オブジェクト・ブラウザMLEモジュール - JavaScriptから、作成したモジュールFACTORIAL_MODを確認します。


Gistを例に取りましたが、HTTPで呼び出すことができればリポジトリは選ばないでしょう。特殊な認証が必要な場合は、一旦データベースにCLOBとして保存した上でJavaScriptモジュールを作成する必要がありそうです。

どちらにしても、DDLからソースコードを除くことにより、CI/CDに載せることが容易になるはずです。

2023年4月12日水曜日

DB 23cのLock Free Reservationを使ってみる

 DB 23cよりLock Free Reservationと呼ばれる機能が追加されました。これは以下の操作を行います。

  • 数値列の操作を加算と減算に限定します。
  • 演算結果を更新する代わりに、差分をジャーナルに保存します。
  • 値が書かれているブロックは変更しないため、ロックを取得しません。値自体は変更されたように見えます。
  • 別のトランザクションが同じ行の同じ列を更新する場合も、ロックを取得せずに差分をジャーナルに保存するので待機が発生しません。
  • トランザクションのコミット時に差分を適用します。
  • SAGAが開始していて(DBMS_SAGA.BEGIN_SAGAが呼び出された後)、SAGAのロールバックが発生した(DBMS_SAGA.ROLLBACK_SAGAが呼びされる)場合は、自動的に補償トランザクションが実行されます。
この機能を実装してみて、実際に効果を確認してみます。SAGAの実装は大変なので、それは除きます。また、仕組みの詳細について解説することは、目的としていません。

効果の確認に、Oracle REST Data ServicesのRESTサービスを使います。

最初に表CALL_COUNTERを作成します。

create table call_counter(
    id number primary key,
    count number
);

あらかじめ1行データを投入します。主キーIDの値はです。UPDATEを実行するときは、条件として主キーの値を指定する必要があります。

insert into call_counter(id, count) values(1, 0);

Lock Free Reservationを有効にする場合は、以下のようにreservableを指定します。

create table call_counter(
    id number primary key,
    count number reservable
);


最初に、Lock Free Reservationなしで作業を進めます。以下のコードがGETハンドラの処理になります。


RESTfulサービスのモジュールとしてcallテンプレートとしてcountを作成し、GETハンドラを作成します。ソース・タイプPL/SQLを選択します。


テストの準備ができたので、同時にRESTサービスを呼び出してみます。RESTサービスの待機時間を含む処理時間は、5、9、12、16秒と増えていきます。countは52、53、54、55となっています。


列countをreservableに変更します。

alter table call_counter modify (count reservable);

ほとんどのリクエストが5秒で終了します。ロック待機が発生していないことが確認できます。また、逐次処理にはなっていないため、countは全部同じ値(以下では55)です。次にRESTサービスを呼び出すと、countは4が加わり59になります。


Lock Free Reservationには、このような効果があります。

reservableとなっている列がある表をドロップしようとすると、ORA-55764が発生します。そのため、表をドロップする前に列をnon reservableに変更する必要があります。

SQL> drop table call_counter;

drop table call_counter

           *

ERROR at line 1:

ORA-55764: Cannot DROP or MOVE tables with reservable columns. First run "ALTER

TABLE <table_name> MODIFY (<reservable_column_name> NOT RESERVABLE)" and then

DROP or MOVE the table.



SQL> 


以上で、Lock Free Reservationの説明は終了です。

ここまで極端なホットスポットはあまり無いとは思います。とはいえ加算と減算に操作を限定できる数値列、例えばページの訪問数やいいねをクリックした数のようなデータがある場合は、適用を検討する価値はあるでしょう。

2023年4月11日火曜日

DB 23cのMLEでJavaScriptモジュールを作成する

 Oracle Database 23c Freeの環境上でJavaScriptのMLEモジュールを作成し、APEXのSQLコマンドより呼び出してみます。

マニュアルの記載部分は以下になります。

JavaScript Developer's Guide
2 MLE JavaScript Modules and EnvironmentsJavaScript Developer's Guide

マニュアルに記載されている例に間違いがあるため、一部を変更しています。最初にMLEモジュール(JavaScriptモジュール)factorial_modを作成します。ファンクションfactorialがエクスポートされます。
CREATE OR REPLACE MLE MODULE factorial_mod LANGUAGE JAVASCRIPT AS

export function factorial(num) {
    if(num < 0) {
        return -1;
    } else if (num == 0) {
        return 1;
    } else {
        return(num * factorial(num-1));
    }
}
/
DDLなので、言語SQLを選択します。


作成されたMLEモジュールはオブジェクト・ブラウザMLEモジュール - JavaScriptより、参照や修正(および新規作成)が可能です。モジュールの本文はDDLに埋め込む以外に、CLOB、BLOBおよびBFILEとして指定することも可能です。


次にMLE環境を作成します。マニュアルの例を少し変更し、環境名やインポート名に小文字を使うようにしました。モジュール名またはインポート名を指定する箇所の違いが分かりやすくなると思います。
CREATE MLE ENV "myFactorialEnv" IMPORTS('factorialMod' MODULE FACTORIAL_MOD);
/
こちらもDDLなので、言語SQLを選択します。


オブジェクト・ブラウザMLE環境より、作成したMLE環境の参照と変更(および新規作成)が可能です。


MLEモジュールFACTORIAL_MODfactorialを呼び出してみます。

以下を実行します。今度はJavaScriptの実行なので、言語JavaScript(MLE)を選択します。また、モジュールのインポートを行うため環境としてmyFactorialEnvを選択します。
const { factorial } = await import('factorialMod');
console.log(factorial(3));
実行すると、結果が表示されます。


SQLコマンドから、MLEモジュールとして作成したファンクションを呼び出すことができました。

SQL Developer Web(データベース・アクション)にも、MLE JSというJavaScriptを実行するツールが含まれています。

スニペットとして全く同じコードを実行してみましたが、解析エラーが発生します。この原因は、今のところ不明です。


エクスポートしたJavaScriptのファンクションfactorialを、SQLから呼び出せるようにします。ファンクションを作成し、JavaScriptのファンクションをSIGNATUREに指定します。
CREATE OR REPLACE FUNCTION js_factorial(
    p_num number)
return number
AS MLE MODULE FACTORIAL_MOD
SIGNATURE 'factorial(number)';
/

ファンクションが作成されたら、以下のSQLを実行し作成したファンクションjs_factorialを呼び出してみます。

select js_factorial(3) from dual;


結果が出力されます。

Oracle APEXのアプリケーションに適用されるMLE環境は、アプリケーション定義セキュリティデータベース・セッションのセクションにあるMLE環境で設定します。


MLEでJavaScriptモジュールを扱う方法の紹介は以上です。

Oracle APEXのアプリケーション作成の参考になれば幸いです。