2022年11月29日火曜日

対話モード・レポートでのテンプレート・ディレクティブの利用

 APEX 22.2より対話モード・レポートとクラシック・レポートでもテンプレート・ディレクティブが利用できるようになりました。

今までは条件ごとに列の表示を切り替えるために、主にCASE句を使用していました。これだとレポートのSELECT文が非常に見難くなります。

APEX 22.2より対話モード・レポートとクラシック・レポートで使用できるようになったテンプレート・ディレクティブにより、レポートのソースのSELECT文がどのように変わるか以下に紹介します。

アプリケーションのページに対話モード・レポートを3つ作成しています。最初の対話モード・レポートデフォルトは表SAMPLE_FILESにテスト・データを投入するために使用します。ページ作成ウィザードによって作成されたフォーム付き対話モード・レポートです。

対話モード・レポート従来の実装では、レポートのソースのSELECT文にCASE句を使っています。対話モード・レポートテンプレート・ディレクティブでは、レポートのソースのSELECT文ではなくテンプレート・ディレクティブで列の表示を切り替えています。

どちらも表示上は同じになっています。


表SAMPLE_FILESの作成


クイックSQLの以下のモデルより、表SAMPLE_FILESを作成しています。

# prefix: sample
files
    name vc80 /nn
    url vc400
    content file

生成されるDDLは以下になります。
create table sample_files (
    id                             number generated by default on null as identity 
                                   constraint sample_files_id_pk primary key,
    name                           varchar2(80 char) not null,
    url                            varchar2(400 char),
    content                        blob,
    content_filename               varchar2(512 char),
    content_mimetype               varchar2(512 char),
    content_charset                varchar2(512 char),
    content_lastupd                date
)
;
今回実装するレポートの列Nameに、以下の設定を行ないます。

列CONTENTにBLOBのデータが保存されている場合は、NameをクリックするとBLOBのデータをダウンロードします。そうでない場合は列URLを開きます。

また、列CONTENT_MIMETYPEよりファイルタイプに応じたアイコンを表示します。


従来の実装



従来の実装でのソースです。




レポートに現れる列はNAMEとTYPEですが、これらは両方ともHTMLなのでセキュリティ特殊文字のエスケープOFFにする必要があります。アプリケーションの安全性が下がります。


また列フィルタタイプとしてデフォルトの列タイプに基づくデフォルトが選択されていると、列のデータ(HTMLのA要素)がそのまま検索条件やソートの条件に使用されます。




テンプレート・ディレクティブ



テンプレート・ディレクティブの使用を前提とした、ソースのSELECT文です。



DOWNLOAD_URLEXTERNAL_URLFILE_EXISTが追加されています。列NAMEとTYPEにテンプレート・ディレクティブを使ったHTML式を記述する際に使用しますが、表示は不要です。これらの列の識別タイプ非表示にします。


NAME列の書式HTML式として、以下を記述します。



先頭の1行はコメントです。

{!#FILE_EXIST#/}

本来であればこの行が無くても同じ動作になるのですが、if文の条件に非表示文字列が使用されていると正しく認識されないという不具合があり、そのワークアラウンドとして先頭に非表示列を含むコメント行を含めています。

TYPEHTML式です。




列NAMEとTYPEともに検索結果のデータ自体はHTMLではないため、セキュリティ特殊文字のエスケープOFFにする必要はありません。より安全な実装になっています。

また、列フィルタの値もHTMLにはなりません。


列TYPEの列フィルタの値は、アイコンではなくMIMEタイプの文字列が表示されます。アイコンでは検索やソートはできないので、文字列が表示される方が実用的といえます。


対話モード・レポートでのテンプレート・ディレクティブの利用方法の紹介は以上になります。

今回使用したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/new-222-template-directive.zip

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