2024年2月9日金曜日

APEX_REGION.OPEN_QUERY_CONTEXT呼び出し時にp_outer_sqlを指定して出力する列を選択する

APEXのPL/SQL APIとして提供されているAPEX_REGION.OPEN_QUERY_CONTEXTの引数のひとつにp_outer_sqlがあります。p_outer_sqlにリージョンのデータ・ソースを囲む形で記述したSELECT文を与えることにより、APEX_REGION.OPEN_QUERY_CONTEXTの出力結果を置き換えることができます。

このp_outer_sqlの使い方のひとつを、以前に記事「ファセットによる検索結果の合計や平均を計算する」で紹介しています。ファセットを適用した検索結果の列SALおよびCOMMの合計、平均、最小値、最大値、件数を別のレポートに表示しています。この例ではAPEX_REGION.OPEN_QUERYに引数p_outer_sqlを指定して、その結果をパイプライン表関数とする、少々複雑な実装を行っています。

本記事では引数p_outer_sqlの、もう少し簡単な使用例を紹介します。こちらの記事「ファセット検索の検索結果をAPEX_REGION.OPEN_QUERY_CONTEXTを呼び出してCSV形式でダウンロードする」にて、ファセット検索の結果をCSVでダウンロードする実装を紹介しています。このダウンロード処理に、引数p_outer_sqlを使って以下の機能を追加します。
  1. CSVへ出力する列を選択する。
  2. 列MGRとDEPTNOの出力を名前ではなく、生データの数値にする。
出力列を選択するページ・アイテムをP3_PRINT_COLUMNSとして作成します。


ページ・アイテムP3_PRINT_COLUMNSには、以下の設定を行います。

タイプチェックボックス・グループです。ラベルPrint Columnsとしていますが、外観テンプレートHiddenを選択しているため表示はされません。レイアウトラベル列スパンにして、テンプレート・オプションStretch From Itemチェックします。列の数10としているため(列の数は8)、選択する列は横一列で、画面の左右いっぱいに表示されます。

セッション・ステートストレージセッションごと(永続)を選びます。ダウンロード処理を実行するAjaxコールバックのプロセスに引数を渡すことができないため、選択した列を保存しているページ・アイテムP3_PRINT_COLUMNSの値は、変更が発生したときにセッション・ステートに保存します。Ajaxコールバックセッション・ステートに保存されたページ・アイテムP3_PRINT_COLUMNSの値を参照します。


LOVタイプ静的値として、表示値戻り値を設定します。


戻り値は必ずレポート列の列名にします。


ページ・アイテムP3_PRINT_COLUMNSに動的アクションを作成します。タイミングイベントとして変更を選択します。


TRUEアクションとしてサーバー側のコードを実行を選択します。送信するアイテムP3_PRINT_COLUMNSを指定し、この動的アクションが呼び出された時に、画面上のページ・アイテムP3_PRINT_COLUMNSの値をデータベースに送信します。データベースは受信した値をセッション・ステートに保存します。ページ・アイテムの値をセッション・ステートに保存するだけであれば、PL/SQLコードの実行は不要です。PL/SQLコードを空にはできないため、null;を記述します。


CSVのダウンロードを実行するPL/SQLコードに、引数p_outer_sqlの指定を追加します。



p_outer_sqlに以下を渡し、出力する列としてEMPNOEmployee NameJobManagerDepartmentを選択してCSVダウンロードを実行します。チェックボックス・グループで複数選択された値は':'(コロン)で区切られています。SELECT文の列として認識されるために','(カンマ)に置き換えています。

l_outer_sql := 'select ' || replace(:P3_PRINT_COLUMS,':',',') || ' from #APEX$SOURCE_DATA#';

置換文字列#APEX$SOURCE_DATA#は、指定したリージョン自体の問い合わせに置き換えられます。この結果セットは、レポート・リージョンに定義された列を持ちます。


以下のCSVファイルがダウンロードされます。


p_outer_sqlに以下を渡すと、列MGRDEPTNOが数値になります。

l_outer_sql := 'select ' || replace(:P3_PRINT_COLUMS,':',',') || ' from emp where empno in (select empno from #APEX$SOURCE_DATA#)';


APEX_REGION.OPEN_QUERY_CONTEXTの引数p_outer_sqlの使い方の紹介は以上になります。

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