2022年8月10日水曜日

MySQLにアクセスするAPEXアプリケーションを作成する

 MySQLに関して、サーバーの準備と接続の準備までができています。

MySQLをAmpere A1インスタンスにインストールする
REST対応SQLサービスによるMySQLへのアクセス

これからMySQLのsakilaサンプル・データベースを使った、APEXアプリケーションを作成してみます。AskTOM Office HourのAPEX 22.1, ORDS and the MySQL Database Serviceを試聴して理解した内容です。

すでにWeb資格証明としてMySQL AccessREST対応SQLサービスとしてMySQLが作成されていることが前提です。アプリケーション作成ウィザードを実行し、名前sakila appとして、空のアプリケーションを作成します。

アプリケーションの作成を実行します。


アプリケーションsakila appが作成されます。




表filmの対話モード・レポートを作成する



ページの作成を実行し、対話モード・レポートを選択します。

名前filmデータ・ソースとしてREST対応SQLサービスを選択します。REST対応SQLサービスとして、作成済みのMySQLを選択します。ソース・タイプとして表/ビューの名前としてfilmを選択します。

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


表/ビューの名前の選択肢として、sakilaデータベースに含まれる表が一覧されます。


MySQLでは大文字と小文字は区別されるため、filmFILMまたはFilmと記述すると別の表とみなされます。

ページが作成されたら、実行します。以下のような対話モード・レポートのページが表示されます。対話モード・レポートのアクションに含まれている操作は、データ・ソースがOracle Databaseのときと変わらず利用できます。フラッシュバックピボットは含まれていません。


Ratingを指定した絞り込みを行う機能を追加します。

まず、Ratingの種類を確認します。

アクショングループ化を実行します。


グループ化する列としてRatingを選択します。ファンクションカウントを選び、Film Idを選択します。

適用をクリックします。


Ratingには、PG、G、NC-17、PG-13、Rが値として含まれていることがわかります。


リージョンfilmにページ・アイテムを作成します。

識別名前P2_RATINGタイプとして選択リストを選びます。ラベルRatingとします。LOVタイプとして静的値を選択します。追加値の表示OFFNULL値の表示ONNULL表示値として-- Ratingの選択 --を記述します。


LOV静的値には、表示値戻り値を同じ値にして、選択可能な値であるPGGNC-17PG-13Rの5行を設定します。


ページ・アイテムP2_RATINGを変更したときに、対話モード・レポートfilmリフレッシュされるようにします。

ページ・アイテムP2_RATING動的アクションを作成します。動的アクション名前onChange P2_RATINGとし、タイミングデフォルトを採用します。(ページ・アイテムの変更がデフォルトのタイミングなので、変更せずに利用できます。)TRUEアクションリフレッシュを選び、影響を受ける要素選択タイプとしてリージョンリージョンfilmを指定します。


リージョンfilmソースWHERE句に以下を記述します。

rating = :P2_RATING or :P2_RATING is null

送信するページ・アイテムとしてP2_RATINGを指定します。


以上で機能追加は完了です。以下のような動作になります。




REST対応SQLサービスよりRESTデータ・ソースを作成する



REST対応SQLサービスより、表filmのデータを取得するRESTデータ・ソースを作成します。バインド変数RATINGを列RATINGへのパラメータとします。作成する対話モード・レポートは、先ほど作成したページと同じになります。

共有コンポーネントRESTデータ・ソースを開きます。


作成済みのRESTデータ・ソースが一覧されます。作成をクリックします。


RESTデータ・ソースの作成として最初からを選択します。

へ進みます。


RESTデータ・ソース・タイプとしてREST対応SQL問合せを選択します。名前film by ratingREST対応SQL参照としてMySQLを選択します。

へ進みます。


SQL問合せとして以下を記述します。

select * from film where rating = :RATING or :RATING is null

検証をクリックしてSELECT文を確認し、へ進みます。


認証が必要ですON資格証明はREST対応SQLに設定されているMySQL Accessになります。

検出をクリックします。


検索結果が表示されます。このままRESTデータ・ソースの作成をクリックしてもよいのですが、データ・プロファイルを確認してみます。


MySQLから取得したデータが、Oracle Databaseのデータ型にマッピングされていることが分かります。

RESTデータ・ソースの作成をクリックします。


RESTデータ・ソースfilm by ratingが作成されます。


作成したRESTデータ・ソースを使って、対話モード・レポートのページを作成します。

ページ作成ウィザードを実行し、対話モード・レポートを選択します。

ページ番号名前film by ratingデータ・ソースとしてRESTデータ・ソースを選択し、RESTデータ・ソースに先ほど作成したfilm by ratingを選択します。

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


Ratingを指定するページ・アイテムP3_RATINGを作成します。設定は先ほど作成したP2_RATINGと同じで、タイプ選択リストLOVタイプ静的値PGGNC-17PG-13Rを静的値として設定します。


RESTデータ・ソースのパラメータRATINGに、としてタイプアイテムアイテムとしてP3_RATINGを割り当てます。


パラメータP3_RATINGの選択を変更したときに、リージョンfilm by ratingをリフレッシュする動的アクションを作成します。これはページ・アイテムP2_RATINGに対して作成したonChange P2_RATINGと同じです。


リージョンfilm by ratingソース送信するページ・アイテムとしてP3_RATINGを指定します。


以上でRESTデータ・ソースを使った対話モード・レポートのページは完成です。ページを実行すると、先ほど作成した対話モード・レポートのページと同じ見え方、動作をします。

RESTデータ・ソースを使用しているため、MySQLより取得したデータはOracle Databaseに一時的に保存できます。そのデータを使いローカル後処理として、オラクル・データベース側でデータの加工を行うことができます。


sakilaデータベースには表languageがあり、いくつかの言語が登録されています。その表をOracle Databaseに作成します。
create table language (language_id number primary key, name varchar2(20) not null);
insert into language values(1, 'English');
insert into language values(2, 'Italian');
insert into language values(3, 'Japanese');
insert into language values(4, 'Mandarin');
insert into language values(5, 'French');
insert into language values(6, 'German');
commit;
SQLワークショップSQLスクリプトで実行し、表LANGUAGEを作成します。


ローカル後処理タイプSQL問合せに変更し、SQL問合せとして以下を記述します。列LANGUAGE_IDを数値から言語名に置き換えています。
select FILM_ID,
       TITLE,
       DESCRIPTION,
       RELEASE_YEAR,
       -- LANGUAGE_ID,
       l.name LANGUAGE,
       ORIGINAL_LANGUAGE_ID,
       RENTAL_DURATION,
       RENTAL_RATE,
       LENGTH,
       REPLACEMENT_COST,
       RATING,
       SPECIAL_FEATURES,
       LAST_UPDATE
  from #APEX$SOURCE_DATA# a join LANGUAGE l on a.language_id = l.language_id
追加した列LANGUAGEは最初は非表示になるため、アクションの設定で表示される行に含めます。


RESTデータ・ソースを定義することにより、MySQLのデータとOracle Databaseのデータを組み合わせた結果を表示することができます。


ファセット検索のページを作成する



表filmを対象としたファセット検索のページを作成します。RESTデータ・ソースを作成します。手順は先ほどのfilm by ratingの作成と同じです。

RESTデータ・ソース・タイプとしてREST対応SQL問合せ名前film for facet searchとします。REST対応SQL参照MySQLです。

へ進みます。


SQL問合せとして以下を記述します。
select
    f.film_id
    , f.title
    , f.description
    , f.release_year
    , l.name language
    , f.rental_duration
    , f.rental_rate
    , f.length
    , f.replacement_cost
    , f.rating
    , f.special_features
    , f.last_update
    , c.name category
    , ga.actors
from film f 
        join language l on f.language_id = l.language_id
        left join film_category fc on f.film_id = fc.film_id
        join category c on fc.category_id = c.category_id
        left join (
            select 
                fa.film_id
                , group_concat(concat(a.first_name,' ',a.last_name) order by a.actor_id) actors
            from film_actor fa join actor a on fa.actor_id = a.actor_id
            group by fa.film_id
        ) ga on f.film_id = ga.film_id
へ進みます。


認証が必要ですON資格証明としてMySQL Accessを選択します。

検出をクリックします。


MySQLより取得されたデータが表示されます。列Actorsについては、カンマ区切りの複数の値になっています。

RESTデータ・ソースの作成をクリックします。


RESTデータ・ソースfilm for facet searchが作成されました。

作成したRESTデータ・ソースを使うファセット検索のページを作成します。

ページ作成ウィザードを実行し、ファセット検索を選択します。


ページ番号名前film searchデータ・ソースとしてRESTデータ・ソースを選択し、RESTデータ・ソースに先ほど作成したfilm for facet searchを選びます。

へ進みます。


作成されるファセットを確認します。TITLEは不要なので、これはチェックを外します

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


ページが作成されたら、ページを実行して動作を確認します。

ファセットの件数の更新が行われ、検索が完了するまでにかなり時間がかかります。実用にするには苦しいレベルです。


ファセットをひとつ追加します。

識別名前P4_ACTORSとします。ソースデータベース列としてACTORSデータ型VARCHAR2が選択されます。この列にはフィルムに参加している俳優がカンマ区切りでリストされています。

ラベルActorsLOVタイプ個別値複数の値タイプ区切りリストを選択し、セパレータ,(カンマ)を指定します。空白の切捨てOFFフィルタの結合OR(和集合)を選択します。


ページを実行し、ファセットActorsを使った検索を行います。

MySQL: MULTI_VALUE_FILTERというエラーが発生します。MySQLでは複数の値を持つファセットを使用することはできません。


検索処理の遅さ、サポートされない機能があるなど、MySQLをデータ・ソースとしてファセット検索を利用するには、かなり無理があります。

これらの問題に対応するため、RESTデータ・ソースを同期化します。同期化した後は、データ・ソースはOracle Databaseの表になります。

RESTデータ・ソースfilm for facet searchを開きます。

最初にデータ・プロファイルの編集を開き、列FILM_IDを主キーとして設定します。


FILM_IDの編集アイコン(鉛筆アイコン)をクリックします。


主キーONに変更し、変更の適用をクリックします。


データ・プロファイルの画面に戻るので、ここでも変更の適用をクリックします。


続いて、同期化の管理を呼び出します。


同期先新規表を選択します。表名FILM_FOR_FACET_SEARCHと入力します。

保存をクリックします。


表の作成をクリックし、同期化表を作成します。


今回は同期化表の定期更新については設定せず、一度だけの実行とします。とはいえRESTデータ・ソースに主キーの設定を加えているので、同期タイプマージを選択します。

保存して実行をクリックします。


最後の同期化の項目が表示されると、同期化表へのデータの同期が完了しています。

ファセット検索のデータ・ソースとして、同期化表を使用する準備ができました。


ページ・デザイナにてページ番号のファセット検索のページを開き、リージョン検索結果ソース同期化表の使用ONに変更します。


ページを実行し、Oracle Databaseに同期したデータを使ってファセット検索を行います。

ファセットActorsによる検索もエラーが発生せず、あまりストレスのない速度でファセット検索が動作しています。ファセット検索の実行でMySQLへのアクセスは発生していないため、この速度は純粋に実行しているOracle Databaseの速度になります。


以上で、MySQLにアクセスするAPEXアプリケーションの作成は完了です。

実際のところ、REST対応SQLを使うとOracle Databaseであっても、APEXアプリケーションの作成方法は、この記事とほぼ同じになります。ただし、Oracle Databaseの場合はデータベースの更新処理も実行できます。

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