Oracle APEXでアプリケーションを作成するには、必ずではないですが、データベースに表がある、ということを前提としています。Oracle APEXを開発している部門を統括しているSenior Vice PresidentのMike Hichwaのツイートにあるように、
With a strong data model the application almost write itself.
であり、Oracle APEXは単にUIを作るためのツールというより、データモデル(スキーマ定義といってもよい)からUIを自動的に生成するツールとして作られています。
とはいえ、データモデルを作る、または、スキーマを定義する、というのは大変な作業であり、さらに言うと、現在あるすべての要件を盛り込むことや、将来発生しうる要件を考慮すること、そういったことができるのかどうかもわかりません。
Oracle DatabaseはJSON形式のドキュメントを列に保存することができます。スキーマの定義を厳密に行えないケースに対応するために、JSONを使うことができます。これから、Oracle APEXでJSONを扱う方法について紹介します。
Oracle DatabaseでJSONを扱う方法を、OracleのBeda HammerschmidtがLIve SQLとYouTubeで紹介しています。タイトルはUsing JSON for FlexfieldsまたはUsing JSON to Implement Flexfieldsです。ここで使用されているEMP表の定義を少々簡単にして、Oracle APEXによるユーザー・インターフェースを開発します。
クイックSQLの以下のモデルから表FF_EMPを作成します。
# prefix: ff
emp
empno num /pk
ename vc50
job vc50
hiredate
sal num
flex json
JSON形式のドキュメントを保存する列は、flexとして定義されています。SQLの生成、SQLスクリプトを保存、レビューおよび実行を順次クリックします。
スクリプト・エディタが開きます。
列FLEXの定義をCLOBからBLOBに変更します。また、Autonomous Databaseであればformat osonの指定を付加します。
flex blob check (flex is json format oson)
JSONのデータはCLOBとしても保存可能ですが、日本語を含むデータをCLOBで保存すると内部的にUTF-16のエンコーディングに変換されるため効率が良くありません。
このスクリプトを実行すると、表FF_EMPが作成されます。
アプリケーションの作成を実行します。確認画面が開くので、そこでもアプリケーションの作成をクリックします。
アプリケーション作成ウィザードが起動します。
アプリケーションの名前はJSON flexfieldの実装とします。フォーム付きの対話モード・レポートのページだけを使用するので、ホーム・ページは削除します。
以上でアプリケーションの作成を実行します。
これで元になるアプリケーションが作成されました。
アプリケーションを実行し、JSONを保存する列FLEXを確認します。
対話モード・レポートのページが開きます。データは未入力であるため、一行もありません。作成をクリックします。
表FF_EMPにデータを入力するフォームが開きます。列FLEXのデータ型はBLOBであるため、ファイル・セレクタがUIになっています。ファイルとしてJSONのデータが存在している場合は、そのファイルを選択すると、列FLEXへJSONデータが保存されます。
Live SQLで紹介されているように、列FLEXとして
{"shoeSize":12, "skills":["oracle", "c", "java"]}
を登録することにします。つまり、数値フィールドであるshoeSizeと、複数の値を持つskillsをフォーム画面から与え、列FLEXにJSON形式で保存します。そのデータを呼び出すときはJSON形式のデータから、shoeSizeとskillsを取り出すことになります。
ページ・デザイナでページ番号2のフォームのページを開きます。
列FLEXに対応するページ・アイテムP2_FLEXを、ビルド・オプションでコメント・アウトします。
ページ・アイテムP2_FLEXの代わりに、shoeSizeに対応するページ・アイテムを追加します。
名前をP2_SHOESIZEとします。タイプは数値フィールドです。ラベルは靴のサイズ、ソースの使用はセッション・ステートの値がNULLの場合のみを設定し、セッション・ステートのストレージはリクエストごと(メモリーのみ)を設定します。
次に、skillsに対応するページ・アイテムを追加します。名前をP2_SKILLSとします。タイプはテキスト・フィールドです。ラベルはスキル(複数)、それ以外はP2_SHOESIZEと同じにします。
上記を保存し、アプリケーションを実行して修正したフォームを開くと、ファイル・セレクタの代わりに靴のサイズとスキル(複数)の2つのフィールドが追加されていることを確認できます。
ページ・デザイナに戻り、列FLEXからP2_SHOESIZE、P2_SKILLSを取り出すプロセス、および、P2_SHOESIZE、P2_SKILLSを列FLEXへ保存するプロセスを作成します。
従業員番号を引数として、靴のサイズとスキルを取り出すプロシージャread_from_jsonを作成します。
プロセスを作成し、レンダリング前のヘッダーの前にあるプロセス初期化フォームFf Empの直下に配置します。
識別の名前はJSON読み取り、タイプはAPIの呼出しを選択します。設定のタイプとしてPL/SQL Procedure or Functionを選択し、作成済みのプロシージャREAD_FROM_JSONが呼び出されるようにします。サーバー側の条件としてタイプにアイテムはNULLではないを選択し、アイテムとしてP2_EMPNOを指定します。
JSONから靴のサイズとスキルを読み取るプロセスを作成しました。次にそれらをJSON形式にし、書き込むプロセスを作成します。
従業員番号を引数として、靴のサイズとスキルをJSONに変換して書き込むプロシージャwrite_to_jsonを作成します。
プロセス・ビューを開きます。プロセスを作成し、プロセスプロセス・フォームEf Empの直下に配置します。
識別の名前はJSON書き込み、タイプはAPIの呼出しを選択します。設定のタイプとしてPL/SQL Procedure or Functionを選択し、作成済みのプロシージャWRITE_TO_JSONが呼び出されるように設定します。サーバー側の条件としてタイプにリクエストは値に含まれるを選択し、値としてCREATE,SAVEを指定します。
取り出しと書き込みのプロセスが登録されたので、実際にデータの入力、編集を行います。フォームを開いて、靴のサイズ(ここでは12)、スキル(ここではoracle c java)を登録して確認します。
作成をクリックしフォームを閉じた後、再度フォームを開いて設定した値を確認します。
最後の対話モード・レポートのSQLに靴のサイズとスキルを表示するよう、変更を加えます。対話モード・レポートのページを開き、ソースのSQL問合せを以下に変更します。
select EMPNO,
ENAME,
JOB,
HIREDATE,
SAL,
e.flex.shoeSize "SHOESIZE",
e.flex.skills "SKILLS"
from FF_EMP e
Oracle APEXでJSON形式のドキュメントを扱う方法の紹介は以上になります。
データの活用を考えたとき、スキーマとして定義できるに越したことはありませんが、そうも行かない場合は多々あるかと思います。そのような場合、JSONが扱えるのはアプリケーションを開発する側に色々なオプションを与えてくれるでしょう。
今回作成したアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/json-flexfield-in-apex.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完