2023年10月11日水曜日

データ・ロード定義のルックアップを使用する

サンプル・アプリケーションを作成しているときに、APEXのインスタンス間でデータの移行を行う必要がありました。

データのダウンロードは、対話モード・レポートのExcelダウンロードを使ってファイルに落としました。ダウンロードしたExcelファイルの取り込むために、データ・ロード定義を作成し、データのロードを行なうページを作成してアップロードを行いました。

移行するデータは2つの表に保存されていて、親子関係があります。それぞれの表の主キーはサロゲート・キー(代理キー)として定義しているため、子となる表をエクスポートする際に、主キーの値ではなく親となるデータの名前を代わりにエクスポートに含めます。

このようなケースで子表のデータをインポートするには、最初に親表のデータをアップロードし、その後、子表をインポートする際に親表の名前をルックアップして主キーの値に置き換えます

データ・ロード定義データ・プロファイルルックアップを設定するのは、少し(かなり?)クセがあって分かりにくいため、以下に設定手順を紹介します。

最初に手順を示すために表を作成し、サンプルとなるデータを生成します。以下のクイックSQLのモデルを使用します。

SAMPLE_RESTAURANTSSAMPLE_MENU_ITEMSが作成されます。/insert 10の指定があるため、それぞれ10行づつのサンプル・データが挿入されます。表SAMPLE_RESTAURANTSが親表、SAMPLE_MENU_ITEMSが子表になります。

SQLの生成SQLスクリプトを保存、続けてレビューおよび実行を行います。


SQLスクリプトの画面で実行確認画面即時実行と続けて、生成されたSQLの実行結果を確認します。

アプリケーションの作成を実行します。確認画面でもアプリケーションの作成をクリックします。


アプリケーション作成ウィザードが起動します。

クイックSQLで定義した表SAMPLE_RESTAURANTSとSAMPLE_MENU_ITEMSの対話モード・レポートとフォームのページがすでにページとして追加されているため、そのままアプリケーションの作成を実行します。


作成されたアプリケーションのRestaurantsのページを開き、対話モード・レポートアクションよりダウンロードを呼び出します。


Excelを選択し、ダウンロードをクリックします。レポートの内容がファイルRestaurants.xlsxとしてダウンロードされます。ダウンロードされたファイルに表SAMPLE_RESTAURANTSの主キーである列IDの値は含まれていません。


同様にMenu Itemsのページを開き、対話モード・レポートに表示されている表SAMPLE_MENU_ITEMSのデータをファイルMenu Items.xlsxとしてダウンロードします。

ファイルには表SAMPLE_MENU_ITEMSの主キー列IDの値は含まれません。また、列RESTAURANT_IDの代わりに、列RESTAURANTとして名前が含まれます。


データのダウンロードは以上で完了です。表SAMPLE_MENU_ITEMSとSAMPLE_RESTAURANTSからすべての行を削除し、Excelファイルのデータを再度ロードします。

delete from sample_menu_items; -- カスケード削除となっているので実行不要
delete from sample_restaurants;


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


最初に親表であるSAMPLE_RESTAURANTSへのデータ・ロード定義を作成します。

作成をクリックします。


データ・ロードの作成最初からとします。

へ進みます。


データ・ロード定義名前Restaurantsとします。ターゲット・タイプ表名としてSAMPLE_RESTAURANTSを選択します。

へ進みます。


サンプル・データソース・タイプとしてファイルのアップロードを選び、ファイルの選択として先ほどダウンロードしたExcelファイルRestaurants.xlsxを選択します。

このExcelのデータはデータ・ロード定義の生成に使用されます。この時点では、表にデータはアップロードされません。

へ進みます。


列のマッピングが表示されます。ソース列(Excelに含まれる列)はすべてマップ先(表SAMPLE_RESTAURANTSの列)が割り当てられています。

表SAMPLE_RESTAURANTSの主キー列IDの値は、行の挿入時に自動生成されます。そのため、列のマッピングには含まれません。

ページの作成および追加をクリックします。データ・ロード定義を作成したのち、ページ作成ウィザードが開きます。


ページ作成ウィザードでは、データ・ロードタイプが選択されデータ・ロードとしてRestaurantsが選択済みです。

ページの名前Load Restaurantsとし、ページの作成をクリックします。


データのロードを行なうページが作成されます。

作成されたページを実行します。


ファイルの選択をクリックし、Restaurants.xlsxを選択します。


Restaurants.xlsxを選択すると、ファイルの内容がプレビューされます。

データのロードを実行します。


ExcelファイルRestaurants.xlsxの内容が表SAMPLE_RESTAURANTSにロードされます。

列IDの値はデータのロード時に自動生成されています。そのため、Restaurants.xlsxをダウンロードした時の列IDの値とは異なっています。


表SAMPLE_RESTAURANTSへのデータ・ロードが完了しました。

表SAMPLE_MENU_ITEMSへのデータ・ロード定義を作成します。最初の手順は、表SAMPLE_RESTAURANTSのときと同じです。

データ・ロード定義名前Menu Itemsとします。表名SAMPLE_MENU_ITEMSを選択します。

へ進みます。


サンプル・データとしてMenu Items.xlsxを選択します。

へ進みます。


Excelに含まれる列RESTAURANTは名前です。表SAMPLE_MENU_ITEMSは列RESTAURANT_IDとして、その名前(列NAME)に対応した表SAMPLE_RESTAURANTSの主キー列IDの値を要求しているため、マップ先はありません。

データ・ロードのページを作成する前に、データ・ロードにルックアップを定義する必要があります。

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


データ・ロード定義Menu Itemsが作成されます。

この定義を編集するため、Menu Itemsを開きます。


データ・プロファイルの編集をクリックします。


データ・プロファイルとしてNAMEDESCRIPTIONPRICEが定義されています。

表SAMPLE_MENU_ITEMSは列NAME、DESCRIPTION、PRICEの他に、主キーである列IDと、表SAMPLE_RESTAURANTSを参照する列RESTAURANT_IDが含まれます。主キーは自動生成であるため、データ・プロファイルに含める必要はありません。

これからExcelファイルの列RESTAURANTの値を変換して(表SAMPLE_RESTRAUNTSをルックアップして)、表SAMPLE_MENU_ITEMSの列RESTAURANT_IDとして保存する設定を追加します。

列の追加をクリックします。


元にExcelに含まれる列RESTAURANTに対応した列を追加します。

列タイプデータ名前RESTAURANTとします。データ型VARCHAR2です。

同じ名前の列がロード先である表SAMPLE_MENU_ITEMSに存在していると、この列の値は表SAMPLE_MENU_ITEMSにロードされます。列RESTAURANTは表SAMPLE_MENU_ITEMSに存在しないため、表にデータがロードされることはありません。この列は表SAMPLE_RESTRAUNTSをルックアップするために使用します。

ソースセレクタ・タイプ名前セレクタとしてrestaurantを指定します。Excel列restaurantを列RESTRAUNTとして選択(セレクト)しています。

作成をクリックします。


データ・プロファイルに列RESTRAUNTが追加されます。続いてルックアップを追加します。

列の追加をクリックします。


列タイプとしてルックアップを選択します。名前RESTAURANT_IDです。表SAMPLE_MENU_ITEMSの列RESTAURANT_IDに、ルックアップされたデータがロードされます。データ型NUMBERです。

ルックアップ表名としてSAMPLE_RESTAURANTSを選択します。戻り列ID (Number)になります。表SAMPLE_RESTAURNTSの列IDの値が戻され、表SAMPLE_MENU_ITEMSの列RESTAURANT_IDとして保存されます。

表の列1NAME(Varchar2)を選択し、データ列1としてRESTAURANTを選択します。表の列はルックアップする表SAMPLE_RESTAURANTSに含まれる列です。対して、データ列はソースであるExcelの列です。先ほどExcelの列RESTAURANTをデータ・プロファイルの列RESTAURANTとして読み込むよう、データ・プロファイルの列を設定しています。ここで、その設定を参照しています。

ルックアップの設定は以上です。作成をクリックします。


データ・プロファイルの列として列タイプがルックアップの列RESTAURANT_IDが追加されました。

変更の適用をクリックし、データ・プロファイルの設定画面を閉じます。


変更の適用をクリックし、データ・ロード定義Menu Itemsの更新を完了します。


ExcelファイルMenu Items.xlsxをロードするページを作成します。

ページ作成ウィザードを起動し、データのロードを選択します。


作成するページの名前Load Menu Itemsとします。データ・ロードとして先ほど作成したMenu Itemsを選択します。

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


データをロードするページが作成されたら実行し、ExcelファイルMenu Items.xlsxをアップロードします。

Menu Items.xlsxの内容がプレビューされます。

データのロードを実行します。


データのロードが完了します。

表SAMPLE_MENU_ITEMSの列IDの値はデータのロード時に自動生成されています。そのため、Menu Items.xlsxをダウンロードした時の列IDの値とは異なっています。また、列RESTAURANT_IDの値も、Menu Items.xlsxをダウンロードした時の列IDの値とは異なっています。


データ・ロード定義のルックアップを設定する手順の紹介は以上になります。

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

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