シングルトン・パイプについては、Oracleの以下のドキュメントで説明されています。
https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/autonomous-database-serverless/doc/autonomous-singleton-pipe.html
上記のドキュメントからはAutonomous Databaseでの23aiに限定されているように見えますが、シングルトン・パイプについてはOracle Database 23ai Free上でも動作することが確認できています。Oracle Database 23aiのDBMS_PIPEのもう一つの拡張機能、永続メッセージングに対するパイプの使用については、(パッケージDBMS_CLOUDに依存しているため)Autonomous Databaseの23aiに限定された機能のようです。
https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/autonomous-database-serverless/doc/autonomous-singleton-pipe.html
上記のドキュメントからはAutonomous Databaseでの23aiに限定されているように見えますが、シングルトン・パイプについてはOracle Database 23ai Free上でも動作することが確認できています。Oracle Database 23aiのDBMS_PIPEのもう一つの拡張機能、永続メッセージングに対するパイプの使用については、(パッケージDBMS_CLOUDに依存しているため)Autonomous Databaseの23aiに限定された機能のようです。
サンプル・データセットのEMP/DEPTをインストールして、APEXアプリケーションを作成します。そのアプリケーションのすべてのページに掲示板のリージョンを作成し、メンテナンスの通知を表示します。
本記事での説明には、SQLワークショップのサンプル・データセットに含まれるEMP/DEPTをインストールしたときに作成できるアプリケーションを使います。
アプリケーションの作成をクリックすると、アプリケーション作成ウィザードが開きます。機能は使わないため、すべてをチェックをクリックしてチェックをすべて外します。
ページの追加をクリックし、空白ページを追加します。ページ名はNoticeとします。
以上でアプリケーションの作成を行います。
アプリケーションが作成されます。
今回はパイプ名をBULLETIN_BOARDとします。
グローバル・ページ(ページ番号0)に掲示板となるリージョンを作成します。
識別の名前は掲示板、タイプとして動的コンテンツを選択します。ソースのCLOBを返すPL/SQLファンクション本体として、以下を記述します。
DBMS_PIPE.RECEIVE_MESSAGEのtimeoutに0を指定し、メッセージの待機時間を0秒にします。l_statusに0が返されるときはキャッシュされたメッセージが存在します。待機時間は0秒ですがメッセージが存在しないときは、タイムアウトを意味する1が返されます。エラーの場合は1より大きい値が返されます。
l_statusが0のとき、キャッシュされたメッセージをunpackしリージョンに表示します。
レイアウトのスロットにBannerを選択し、掲示板をページの一番上に表示させます。外観のテンプレートに装飾の無いBlack with Attributesを選択し、掲示板の見え方はシングルトン・パイプにキャッシュしたメッセージで決めるようにします。
サーバー側の条件のタイプに式、言語にPL/SQLを選択し、PL/SQL式として以下を記述します。
0 = dbms_pipe.receive_message(pipename => :PIPE_NAME,timeout => 0)
シングルトン・パイプにキャッシュされたメッセージが存在するときに限り、掲示板を表示します。
シングルトン・パイプにメッセージをキャッシュする、または、キャッシュをパージする機能を、ページNoticeに実装します。
掲示板に表示するメッセージを設定するボタンを作成します。
識別のボタン名はSET_MESSAGE、ラベルはSet Messageです。動作のアクションはデフォルトのページの送信とします。
キャッシュされたメッセージをパージするボタンを作成します。
識別のボタン名はPURGE、ラベルはPurgeです。動作のアクションはデフォルトのページの送信とします。レイアウトの新規行の開始をオフにし、ボタンSET_MESSAGEの右横に配置します。
メッセージを書き込むページ・アイテムを作成します。
識別の名前はP7_MESSAGE、タイプはテキスト領域を選択します。セッション・ステートのストレージはセッションごと(永続)を選択します。
掲示板に表示するメッセージはHTMLを想定しているため、このページ・アイテムにはHTMLを直接記述します。タイプをリッチ・テキスト・エディタとして書式にHTMLを選択すると、メッセージの記述にリッチ・テキスト・エディタを使うことができます。
すでにキャッシュされたメッセージがあれば、ページ・アイテムP7_MESSAGEをそのメッセージで初期化するプロセスを作成します。
レンダリング前のヘッダーの前にプロセスInitを作成します。ソースのPL/SQLコードとして、以下を記述します。
メッセージをシングルトン・パイプにキャッシュするプロセスを作成します。
識別の名前はSet Message、ソースのPL/SQLコードとして、以下を記述します。
declare
l_status integer;
begin
dbms_pipe.pack_message(:P7_MESSAGE);
l_status := dbms_pipe.send_message(:PIPE_NAME);
end;
サーバー側の条件のボタン押下時にSET_MESSAGEを指定します。
シングルトン・パイプにキャッシュしたメッセージをパージするプロセスを作成します。
識別の名前はPurge、ソースのPL/SQLコードとして、以下を記述します。
begin
dbms_pipe.purge(:PIPE_NAME);
end;
サーバー側の条件のボタン押下時にPURGEを指定します。
作成したアプリケーションを実行する前に、メッセージをキャッシュするシングルトン・パイプを作成します。pipenameはBULLETIN_BOARDです。キャッシュの有効期限として引数shelflifeに3600秒を設定しています。
declare
l_status integer;
begin
l_status := dbms_pipe.create_pipe(
pipename => 'BULLETIN_BOARD'
,private => true
,singleton => true
,shelflife => 3600
);
end;
作成済みのパイプはv$db_pipesから確認できます。デフォルトではAPEXワークスペースにSELECT権限が与えられていないため、ユーザーADMINでSELECT権限を与えておく必要があります。
select * from v$db_pipes
DBMS_PIPE.CREATE_PIPEを再度呼び出すことにより、キャッシュの有効期限を変更することができます。すでにシングルトン・パイプが作成済みでもエラーは発生しないようです。
記事の先頭のGIF画像で設定しているメッセージは以下です。
<div style="background-color: var(--u-color-6)">
<div class="u-flex u-align-items-center">
<div class="margin-auto u-bold margin-top-sm margin-bottom-sm">今晩、メンテナンスが予定されています。</div>
</div>
</div>
今回の記事は以上になります。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-singleton-dbms-pipe.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完