2023年10月5日木曜日

レポートのソースに含まれる計算結果の列の扱い

対話モード・レポートのデータ・ソースとなるSELECT文の列として、計算した値を含めた際にどのような設定が必要になるのか、といった質問がありました。計算した結果の列は更新できません。

サンプル・データセットのEMP/DEPTに含まれる表EMPを使って、必要な設定について紹介します。

レポートのソースとなるSELECT文に勤続日数を追加します。
select EMPNO,
       ENAME,
       JOB,
       MGR,
       HIREDATE,
       floor(SYSDATE - HIREDATE) "勤続日数",
       COMM,
       DEPTNO
from EMP
すでにアプリケーションが作成済みとします。

ページ作成ウィザードを使用して、上記のSELECT文をソースとした対話モード・レポートとフォームのページを作成します。

ページの作成をクリックします。


対話モード・レポートを選択します。


ページ定義フォームを含めるオンにし、生成されるページにフォームを含めます。レポートのページの名前従業員一覧フォーム・ページ名従業員編集とします。

データ・ソースソース・タイプとしてSQL問合せを選択し、SQL SELECT文を入力として、勤続日数を列定義に含んだSELECT文を記述します。

ナビゲーションは変更せず、ブレッドクラムの使用ナビゲーションの使用ともにオンとします。

へ進みます。


主キー列1としてEMPNO (Number)を選択します。

ページの作成を実行します。


以上で対話モード・レポートとフォームの2つのページが作成されます。

アプリケーションを実行し、対話モード・レポートを表示します。

こちらはソースとして定義したSELECT文に含まれる勤続日数が、そのまま表示されています。


編集フォームを開き、変更の適用をクリックしてデータを更新しようとすると、ORA-01733: ここでは仮想列は使用できません。というオラクル・データベースのエラーが発生します。これは計算結果である勤続日数を更新しようとしているため、発生しています。


この対処方法は以下になります。

ページ・デザイナでフォームのページを開きます。

ページ・アイテムP3_勤続日数を選択し、ソース問合せのみオンに変更します。この変更により勤続日数は更新対象ではなくなるため、エラーは発生しなくなります。また、勤続日数は計算された結果ですからユーザーが入力することはありません。そのためタイプ表示のみにします。


フォームの項目より勤続日数を削除することによって、対応することも可能です。この場合、フォームに勤続日数は表示されなくなります。

従業員編集のリージョンを開き、ソースSQL問合せに記述されているSELECT文より、勤続日数の列を削除します。


その後に、リージョン従業員編集の上でコンテキスト・メニューを開き、ページ・アイテムの同期化を実行します。


ソースとなるSQLより勤続日数の列が無くなっているため、ページ・アイテムP3_勤続日数も無くなります。


フォームからも勤続日数のフィールドが無くなります。

勤続日数自体が無くなっているため更新処理は発生せず、エラーも発生しなくなります。


レポートとフォームでの計算列の扱いについては以上です。

最後にデータ・ロードについて説明します。

対話モード・レポートのアクションより、ダウンロードを実行します。


Excelを選択し、ダウンロードを実行します。

従業員一覧.xlsxというファイルが、手元にダウンロードされます。


このダウンロードされたExcelファイルには、列として勤続日数が含まれます。そのため、このファイルを表EMPにロードするには、勤続日数を除外する必要があります。


SQLワークショップオブジェクト・ブラウザを開き、表EMPを切り詰めます(トランケートします)。

EMPを選択し、その他から表を切り詰めるを実行します。


確認画面に実行されるSQLが表示されます。切捨てをクリックすると、表EMPが空になります。


対話モード・レポートのページに戻りページを再ロードすると、表EMPが空になっていることが確認できます。


これから、先ほどダウンロードした従業員一覧.xlsxをデータベースにロードするページを作成します。

共有コンポーネントデータ・ロード定義を開きます。


作成をクリックし、データ・ロード定義の作成を始めます。


データ・ロードの作成最初からです。

へ進みます。


データをロードするターゲット名前従業員ロードとします。ターゲット・タイプ表名としてEMPを選択します。

Excelファイル従業員一覧.xlsxの内容は、表EMPに保存されます。

へ進みます。


サンプル・データソース・タイプとしてファイルのアップロードを選び、ファイルの選択をクリックして従業員一覧.xlsxを選択します。

このデータはデータ・ロード定義の作成に使用され、この時点ではデータベースの表EMPにロードされません。

へ進みます。


列のマッピングの定義が開きます。

ターゲットとなる表に保存先がない列(今回の例では勤続日数)は、マップ先を空白(未マップ)にしてください。データのロード対象から外されます。

ページの作成および追加を実行します。


ページ作成ウィザードが起動します。

新しく作成されるデータ・ロードを行うページに名前を付けます。今回はデータロードとしました。

ページの作成をクリックします。


作成されたページを実行し、Excelファイル従業員一覧.xlsxを表EMPにロードします。


ファイルの選択をクリックし、従業員一覧.xlsxを選択します。


ロードされるデータのプレビューが表示されます。この画面には勤続日数が表示されていますが、データベースにはロードされません。

データのロードをクリックします。


データ・ロード終了というメッセージが表示されます。


従業員一覧の対話モード・レポートを開くと、Excelファイルの内容が反映されていることが確認できます。


計算結果の列の扱いについての説明は以上になります。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-calculated-column.zip

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