シングルトン・パイプについては、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ファンクション本体として、以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_message varchar2(32767); | |
l_status integer; | |
begin | |
l_status := dbms_pipe.receive_message( | |
pipename => :PIPE_NAME | |
,timeout => 0 | |
); | |
if l_status > 0 then | |
return null; | |
end if; | |
dbms_pipe.unpack_message(item => l_message); | |
return to_clob(l_message); | |
end; |
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コードとして、以下を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare | |
l_message varchar2(32767); | |
l_status integer; | |
begin | |
l_status := dbms_pipe.receive_message( | |
pipename => :PIPE_NAME | |
,timeout => 1 | |
); | |
if l_status = 0 then | |
dbms_pipe.unpack_message(item => l_message); | |
:P7_MESSAGE := l_message; | |
else | |
:P7_MESSAGE := ''; | |
end if; | |
end; |
メッセージをシングルトン・パイプにキャッシュするプロセスを作成します。
識別の名前は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のアプリケーション作成の参考になれば幸いです。
完