Oracle Applications開発者ガイド リリース12 E06048-01 | 目次 | 前へ | 次へ |
この項では、表および追加する必須列の定義方法の仕様を説明します。また、LONGおよびLONG RAWなどの特別なデータ型、および宣言制約についても説明します。
Oracle Applicationsでは、旧バージョンで使用していたルールベース最適化(RBO)のかわりにコストベース最適化(CBO)を使用します。コストベース最適化を利用するには、新規コードをすべて作成する必要があります。ルールベース最適化を利用するようにカスタム・アプリケーション・コードを調整している場合は、コストベース最適化向けのコードに再調整することが必要な場合があります。
詳細は、Oracleデータベースのチューニングに関するマニュアルを参照してください。
レコード履歴(WHO)機能は、Oracle Applicationsの表の行の作成者または更新者についての情報をレポートします。Oracle Applicationsのアップグレード・テクノロジでは、レコード履歴(WHO)を使用してカスタマイズを検出および保持します。
表に特別なWHO列を、フォームおよびストアド・プロシージャにWHOロジックを追加すると、ユーザーはデータに加えられた変更を追跡できます。WHO列を参照することにより、フォームによって加えられた変更と、コンカレント・プログラムによって加えられた変更を区別できます。
(基礎となる各表のWHO列に対応する)フォームの各ブロックでは、WHO列はそれぞれ非表示フィールドとして表します。これらのフィールドを移入するには、PRE-UPDATEおよびPRE-INSERTでFND_STANDARD.SET_WHOをコールします。
次の表に、レコード履歴(WHO)に使用される標準列、列の属性および説明、およびこれらの列の値のソースをリストします。CREATED_BY列およびCREATION_DATE列は、(フォームにFND_STANDARD.SET_WHOを使用して)行を挿入する場合にのみ設定します。
列名 | タイプ | NULL? | 外部キー? | 説明 | 値 |
---|---|---|---|---|---|
CREATED_BY | NUMBER(15) | NOT NULL | FND_ USER | 各行を作成したユーザーの履歴を記録 | TO_NUMBER (FND_ PROFILE. VALUE ('USER_ID')) |
CREATION_ DATE | DATE | NOT NULL | 各行が作成された日付を保存 | SYSDATE | |
LAST_ UPDATED_BY | NUMBER(15) | NOT NULL | FND_ USER | 各行を最後に更新したユーザーの履歴を記録 | TO_NUMBER (FND_ PROFILE. VALUE ('USER_ID')) |
LAST_UPDATE_ DATE | DATE | NOT NULL | 各行が最後に更新された日付を保存 | SYSDATE | |
LAST_UPDATE_ LOGIN | NUMBER(15) | FND_ LOGINS | 各行を最後に更新したユーザーがオペレーティング・システムへログインした情報へのアクセスを提供 | TO_NUMBER (FND_ PROFILE. VALUE ('LOGIN_ ID')) |
コンカレント・プログラムにより更新される可能性のある表には、追加の列も必要です。次の表に、レコード履歴(WHO)に使用されるコンカレント処理列、列の属性および説明、およびこれらの列の値のソースをリストします。
列名 | タイプ | NULL? | 表への外部キー? | 説明 |
---|---|---|---|---|
REQUEST_ID | NUMBER(15) | FND_ CONCURRENT_ REQUESTS | この行の作成または更新時に実行中だったコンカレント要求の履歴を記録 | |
PROGRAM_ APPLICATION_ ID | NUMBER(15) | FND_ CONCURRENT_ PROGRAMS | PROGRAM_IDと併用して、各行を作成または更新したコンカレント・プログラムの履歴を記録 | |
PROGRAM_ID | NUMBER(15) | FND_ CONCURRENT_ PROGRAMS | PROGRAM_ APPLICATION_IDと併用して、各行を作成または更新したコンカレント・プログラムの履歴を記録 | |
PROGRAM_ UPDATE_DATE | DATE | PROGRAM_ UPDATE_ DATE | コンカレント・プログラムが各行を作成または更新した日付を保存 |
コミット時に必要な操作には、表ハンドラ用に設計されていないように思われるものがいくつかあります。たとえば、レコードのレコード履歴情報の設定または連番の決定には、表ハンドラよりもイベント・ハンドラが使用されます。このような操作のロジックは、PRE_INSERTまたはPRE_UPDATEイベント・ハンドラ(あるいはその両方)に格納され、挿入または更新時にPRE-INSERTおよびPRE-UPDATEブロックレベルのトリガーからコールされます。
関連項目: FND_STANDARD: 標準API
CREATION_OR_LAST_UPDATE_DATEプロパティ・クラスをCREATION_DATEおよびLAST_UPDATE_DATEフォーム・フィールドに適用します。このプロパティ・クラスは、データ型および幅を含め、これらのフィールドに正しい属性を設定します。
行を処理できるかどうか判断するのにレコード履歴列を使用しないでください。正しい情報を含むこれらの列に依存しないでください。
一般的に、HR_EMPLOYEESに対するレコード履歴列の解決は行いません。そのような結合を試行する場合、結合は外部結合である必要があります。
表に基づき、ただしレコード履歴情報のないブロックでは、メニュー・エントリ「HELP」->「ABOUT_THIS_RECORD」は使用できません(他のケースはすべて、デフォルトのメニュー・コントロールで処理します)。
次の行を使用し、(「オーバーライド」スタイルで)ブロックレベルのWHEN-NEW-BLOCK-INSTANCEトリガーのコードを作成します。
app_standard.event('WHEN-NEW-BLOCK-INSTANCE');
app_special.enable('ABOUT', PROPERTY_OFF);
関連項目: APP_SPECIAL: メニューおよびツールバー・コントロール
この項では、Oracleデータベースが表に許可する宣言制約と、各機能をいつOracle Applicationsの表で使用するかを説明します。
ほとんどの箇所において、表に関連付けられている制約は、制約に違反する場合、ユーザーがフィードバックを即時に受けられるように複製する必要があります。
警告: 自分でOracle Applicationsの表に制約を追加作成しないでください。Oracle Applicationsのアップグレードに影響を及ぼす場合があります。制約を追加作成する場合は、Oracle Applicationsをアップグレードする前に無効化してください。
必要に応じて使用します。対応するフィールドを、Oracle Forms内で"Required" = Trueとして宣言します。
Oracle Formsとのロック問題が発生する可能性があるため、一般的にこの機能は使用しません。フォームによって使用されない表(たとえば、バッチ・プログラムによって使用される表)、またはフォームによって維持されない列を含む表には使用できます。たとえば、列値をデフォルト化することにより、バッチ・プログラムを簡単にできます。可能なデフォルト値は、SYSDATE、USER、UID、USERENV()、または任意の定数値です。
必要に応じて使用します。一意キーにNULLが含まれることがありますが、このような場合でも、キーは一意である必要があります。キー列のすべてにNULLの行がいくつも含まれる場合は例外です。
さらに、フォームに一意性チェックを実装するには、引数としてROWIDおよび表の一意キーを取り、キーが一意でない場合に例外を発行するPL/SQLストアド・プロシージャを作成します。フォーム内で一意性チェックを行うのは、ユーザーが入力できるフィールドのみです。システム生成の一意値は、一意であることが保証された順序から導出される必要があります。
関連項目: 一意性チェック
この機能は、有効な値のリストが静的で短い(つまり「Y」または「N」)簡単なケースにおいてのみ、列値が有効かどうかをチェックするのに使用します。
CHECKは、主にデータベース・トリガーへの複製機能を提供しますが、PL/SQLプロシージャをコールする柔軟性はありません。PL/SQLプロシージャをコールするトリガーをかわりに使用することで、フォームと制約を共有し、検証を調整して冗長性を回避できます。
データベース・トリガーでは、トリガーが有効な際に挿入、更新、または削除された行のみを検証しますが、CHECKでは、表のすべての行が正常に制約にパスすることを保証します。
Oracle Applicationsのデータベース・トリガーはまれにしか無効化されないため、これは通常は心配する必要はありません。一部のトリガー(警告イベントなど)はアップグレード前に無効化され、アップグレードの最後に再有効化されます。
データベース・トリガーの使用は避けることをお薦めします。
すべての表の主キーを定義します。
表を定義する際には、宣言カスケード削除または外部キー制約は使用しないでください。カスケード削除は分散データベース全体にわたっては機能しないため、必要な箇所すべてにカスケード削除ロジックを作成する必要があります。
参照整合性検査を実装するには、引数として表の一意キーを取り、行の削除により参照整合性エラーが発生する場合に例外を発生するPL/SQLストアド・プロシージャを作成します。
関連項目: 整合性チェック
LONG、LONG RAWまたはRAWデータ型を使用した表の作成は避けてください。Oracle Forms内では、ワイルドカードを使用してこれらの型の列を検索することはできません。かわりにVARCHAR2(2000)列を使用してください。
名前にPL/SQLまたはOracle Formsの予約語を含む列が表に存在する場合、列の名前を別名にするビューを表に作成する必要があります。このビューは他の表に結合しないため、挿入、更新および削除を通常どおり実行できます。
一般に、複雑なブロックはビューに基づき、単純な設定のブロックは表に基づきます。ビューの使用には、次のような利点があります。
すべての外部キーがサーバーで非正規化されるため、ネットワークの通信量が最小限になります。
非データベース・フィールドを移入するPOST-QUERYロジックを作成する必要がありません。
非データベース・フィールドに対して入力して問合せを実装するPRE-QUERYロジックはコーディングする必要がありません。
値リスト(LOV)をビューのベースにする必要があります。これにより、LOV定義を集中管理および共有できます。LOVビューには非正規化された列が少なく、有効なデータ行のみが含まれるため、LOVビューは通常ブロック・ビューよりも単純です。
関連項目: 値リストの例
パフォーマンスが問題になり、表に外部キーが含まれる場合、パフォーマンスを改善するためにビューを定義する必要があります。ビューにより、1つのSQL文が外部キーを処理することになり、サーバーによる解析が減少し、ネットワークの通信量が減少します。
データベースで使用可能なオブジェクトは、すべてのクライアントまたはサーバー側のコードからアクセスできるため、モジュール性および再利用が促進されます。ビューが必要とされる理由は次のとおりです。
開発者はすでにカプセル化されているロジックに基づくことができるため、開発時間を短縮できます。
コードをモジュール化します。これは、修正または拡張を1箇所で行えることを意味します。
ネットワークの通信量を減少させます。
レポートまたは他のアクティビティに有用です。
顧客サイトで容易かつ集中的にパッチを当てることができます。
ビューを使用するSQL文が1つのみの場合、ビューの作成は避けてください。SQL文を含むコードとビューの両方を維持する必要があるため、1つのプロシージャのみが使用するビューを作成するとメンテナンスの負荷が増加します。
ビューの最初の列としてルート表のROWID疑似列を選択し、ビューにおいてROWID疑似列をROW_IDという別名にする必要があります。WHO列、および外部キー情報を含め、ルート表の列すべてがビューに含まれる必要があります。
ヒント: Oracle Formsブロックがこのビューに基づいている場合、含める必要があるのはROWID列のみです。ROW_ID疑似列に対応するOracle Formsフィールドは、ROW_IDプロパティ・クラスを使用する必要があります。
Oracle Formsでは、ビューに基づくブロックのOracle FormsデフォルトのROWID参照を停止するため、ブロックの「キー・モード」プロパティを「更新不可」に変更する必要があります。項目レベルの「主キー」プロパティを「TRUE」に設定し、ビューの主キーを指定します。
たとえば、EMP表に基づくビューに、ROW_ID、EMPNO、ENAME、DEPTNOおよびDNAME列があるとします。ブロックEMP_Vの「キー・モード」プロパティを「更新不可」に、EMPNOの「主キー」プロパティを「TRUE」に設定します。
ブロックが表に基づいている場合、ブロックのキー・モードは「一意」です。
ビューのベースがブロックの際は、ビューのかわりにルート表を挿入、更新、削除およびロックする、ON-INSERT、ON-UPDATE、ON-DELETEおよびON-LOCKトリガーのコードを作成する必要があります。
関連項目: 表ハンドラのコーディング
挿入、更新、削除およびロックのトリガーは、単一表ビューには必要ありません。ブロックのキー・モードを「一意」に設定します。単一表ビューにROW_ID列は必要ありません。
サーバー側で(ASCII数字による文字の定義に使用される)CHR()関数を使用しないでください。使用すると、MVSなどのEBCDIC文字を使用するサーバー側プラットフォームで問題が発生します。ビュー定義にタブまたは改行を埋め込む必要はありません。
この項では、順序の作成および使用に関する標準を説明します。
1つの順序を使用して、1つの表の1つの列に対する一意のID値を提供します。
CYCLEオプションを使用してラップする順序、またはMAXVALUEが指定されている順序は作成しないでください。順序の全範囲が広くなりすぎるため、上限に達することは現実的にはありえません。
通常は、ラップする順序、または範囲に制限のある順序は設計しないでください。
PL/SQL内に順序値を格納するには、NUMBERデータ型を使用します。
順序値を生成する順序をCコードで扱う必要がある場合、順序が生成した値がC言語のlong型変数に適合すると想定しないでください。昇順順序の最大値は10^27ですが、C言語のsigned long integerの最大値は10^9です。10^9が順序の制限として適切ではない場合、long integerのかわりにdoubleを使用することがあります。順序にdoubleを使用する場合、少数値の精度が低くなる場合があるので注意してください。算術を行わず、単に出力または格納のため順序をフェッチする場合は、文字列で順序を取得することを考えてください。
順序値の提供にFND_UNIQUE_IDENTIFIER_CONTROL表を使用しないでください。順序または順次採番パッケージをかわりに使用してください。FND_UNIQUE_IDENTIFIER_CONTROLは廃止されており、この製品ではオブジェクトに対して行は存在しません。
また、アプリケーション固有のFND表を作成してFND_UNIQUE_IDENTIFIER_CONTROL表と置き換えることも避けてください。
AD_DDパッケージのPL/SQLルーチンを使用して、カスタム・アプリケーション表を登録します。
この情報に依存する機能または製品は、フレックスフィールドおよびOracle Alertのみです。したがって、フレックスフィールドまたはOracle Alertで使用する場合にのみ、表(および列すべて)を登録します。AD_DD APIは、後で表を変更する際に、Oracle Application Object Libraryの表からの表および列の登録削除にも使用できます。
後で表を変更する場合は、表登録ルーチンへの修正済または新規のコールを含める必要があります。登録を変更するには、まず登録を削除してから表または列を再登録します。最初に列の登録を削除し、次に表の登録を削除してください。
PL/SQLスクリプトに表登録ルーチンへのコールを含める必要があります。表は自分のアプリケーション・スキーマに作成しますが、APPSスキーマに対してAD_DDプロシージャを実行する必要があります。変更を反映させるには、変更をコミットします。
AD_DD APIは、データベース・スキーマに登録済の表または列が存在するかどうかはチェックせず、必要なAOL表を更新するのみです。登録済の表および列が実際に存在し、AD_DD APIを使用して定義したものと同じ形式であるかを確認してください。ビューは登録する必要ありません。
procedure register_table (p_appl_short_name in varchar2,
p_tab_name in varchar2,
p_tab_type in varchar2,
p_next_extent in number default 512,
p_pct_free in number default 10,
p_pct_used in number default 70);
procedure register_column (p_appl_short_name in varchar2,
p_tab_name in varchar2,
p_col_name in varchar2,
p_col_seq in number,
p_col_type in varchar2,
p_col_width in number,
p_nullable in varchar2,
p_translate in varchar2,
p_precision in number default null,
p_scale in number default null);
procedure delete_table (p_appl_short_name in varchar2,
p_tab_name in varchar2);
procedure delete_column (p_appl_short_name in varchar2,
p_tab_name in varchar2,
p_col_name in varchar2);
変数 | 説明 |
---|---|
p_appl_short_ name | 表を所有するアプリケーションのアプリケーション短縮名(通常はカスタム・アプリケーション)。 |
p_tab_name | 表の名前(大文字表記)。 |
p_tab_type | トランザクション表には「T」を(ほとんどすべてのアプリケーション表)、シード・データ表には「S」を使用(Oracle Applications製品のみで使用)。 |
p_pct_free | 今後の表の更新用に予約された、表の各ブロックにおける領域の割合(1 - 99)。p_pct_freeとp_pct_usedの合計が100より少ないことが必要です。 |
p_pct_used | 表の各データ・ブロックの使用済領域の最小割合(1 - 99)。p_pct_freeとp_pct_usedの合計が100より少ないことが必要です。 |
p_col_name | 列の名前(大文字表記)。 |
p_col_seq | 表の列の順序番号(表定義での列の順序)。 |
p_col_type | 列の型(「NUMBER」、「VARCHAR2」、「DATE」など)。 |
p_col_width | 列のサイズ(数値)。(特定の幅がないかぎり)DATE列には9を、NUMBER列には38を使用。 |
p_nullable | 列が必須の場合は「N」を、NULL値を許可する場合は「Y」を使用。 |
p_translate | 列値がOracle Applications製品リリース用に変換される場合は「Y」を(Oracle Applications製品のみで使用)、変換されない場合は「N」を使用(ほとんどのアプリケーション列)。 |
p_next_extent | 次エクステントのサイズ(単位はKB)。「K」を含めない。 |
p_precision | 数値全体の桁数。 |
p_scale | 数値の小数点以下の桁数。 |
フレックスフィールドの表とその列を登録するAD_DDパッケージの使用例を次に示します。
EXECUTE ad_dd.register_table('FND', 'CUST_FLEX_TEST', 'T', 8, 10, 90);
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'APPLICATION_ID', 1, 'NUMBER', 38, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'ID_FLEX_CODE', 2, 'VARCHAR2', 30, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'LAST_UPDATE_DATE', 3, 'DATE', 9, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'LAST_UPDATED_BY', 4, 'NUMBER', 38, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'UNIQUE_ID_COLUMN', 5, 'NUMBER', 38, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'UNIQUE_ID_COLUMN2', 6, 'NUMBER', 38, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SET_DEFINING_COLUMN', 7, 'NUMBER', 38, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SUMMARY_FLAG', 8, 'VARCHAR2', 1, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'ENABLED_FLAG', 9, 'VARCHAR2', 1, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'START_DATE_ACTIVE', 10, 'DATE', 9, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'END_DATE_ACTIVE', 11, 'DATE', 9, 'N', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SEGMENT1', 12, 'VARCHAR2', 60, 'Y', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SEGMENT2', 13, 'VARCHAR2', 60, 'Y', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SEGMENT3', 14, 'VARCHAR2', 60, 'Y', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SEGMENT4', 15, 'VARCHAR2', 60, 'Y', 'N');
EXECUTE ad_dd.register_column('FND', 'CUST_FLEX_TEST', 'SEGMENT5', 16, 'VARCHAR2', 60, 'Y', 'N');