ヘッダーをスキップ

Oracle E-Business Suite開発者ガイド
リリース12.2
E53035-01
目次へ
目次
前のページへ
前へ
次のページへ
次へ

データベース・オブジェクトの構築

データベース・オブジェクト作成の概要

この項では、データベース・オブジェクトの定義方法の仕様を説明します。これには、表および追加する必須列の定義に関する情報が含まれます。また、LONGおよびLONG RAWなどの特別なデータ型、および宣言制約についても説明します。

コストベース最適化の使用

Oracle E-Business Suiteでは、旧バージョンで使用していたルールベース最適化(RBO)のかわりにコストベース最適化(CBO)を使用します。コストベース最適化を利用するには、新規コードをすべて作成する必要があります。ルールベース最適化を利用するようにカスタム・アプリケーション・コードを調整している場合は、コストベース最適化向けのコードに再調整することが必要な場合があります。

詳細は、『Oracle E-Business Suiteメンテナンス・ガイド』のOracle E-Businessおよび問合せ最適化に関する項、およびOracleデータベースのチューニングに関するマニュアルを参照してください。

レコード履歴を使用したデータ変更の追跡(WHO)

レコード履歴(WHO)機能は、Oracle E-Business Suiteの表の行の作成者または更新者についての情報をレポートします。Oracle E-Business Suiteのアップグレード・テクノロジでは、レコード履歴(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

WHOフィールドのプロパティ・クラス

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データベースが表に許可する宣言制約と、各機能をいつOracle E-Business Suiteの表で使用するかを説明します。

ほとんどの箇所において、表に関連付けられている制約は、制約に違反する場合、ユーザーがフィードバックを即時に受けられるように複製する必要があります。

警告: 自分でOracle E-Business Suiteの表に制約を追加作成しないでください。Oracle E-Business Suiteのアップグレードに影響を及ぼす場合があります。制約を追加作成する場合は、Oracle E-Business Suiteをアップグレードする前に無効化してください。

NOT NULL

必要に応じて使用します。対応するフィールドを、Oracle Forms内で"Required" = Trueとして宣言します。

DEFAULT

Oracle Formsとのロック問題が発生する可能性があるため、一般的にこの機能は使用しません。フォームによって使用されない表(たとえば、バッチ・プログラムによって使用される表)、またはフォームによって維持されない列を含む表には使用できます。たとえば、列値をデフォルト化することにより、バッチ・プログラムを簡単にできます。可能なデフォルト値は、SYSDATE、USER、UID、USERENV()、または任意の定数値です。

UNIQUE

必要に応じて使用します。一意キーにNULLが含まれることがありますが、このような場合でも、キーは一意である必要があります。キー列のすべてにNULLの行がいくつも含まれる場合は例外です。

さらに、フォームに一意性チェックを実装するには、引数としてROWIDおよび表の一意キーを取り、キーが一意でない場合に例外を発行するPL/SQLストアド・プロシージャを作成します。フォーム内で一意性チェックを行うのは、ユーザーが入力できるフィールドのみです。システム生成の一意値は、一意であることが保証された順序から導出される必要があります。

関連項目: 一意性チェック

CHECK

この機能は、有効な値のリストが静的で短い(つまり「Y」または「N」)簡単なケースにおいてのみ、列値が有効かどうかをチェックするのに使用します。

CHECKは、主にデータベース・トリガーへの複製機能を提供しますが、PL/SQLプロシージャをコールする柔軟性はありません。PL/SQLプロシージャをコールするトリガーをかわりに使用することで、フォームと制約を共有し、検証を調整して冗長性を回避できます。

データベース・トリガーでは、トリガーが有効な際に挿入、更新、または削除された行のみを検証しますが、CHECKでは、表のすべての行が正常に制約にパスすることを保証します。

Oracle E-Business Suiteのデータベース・トリガーはまれにしか無効化されないため、これは通常は心配する必要はありません。一部のトリガー(警告イベントなど)はアップグレード前に無効化され、アップグレードの最後に再有効化されます。

データベース・トリガーの使用は避けることをお薦めします。

PRIMARY KEY

必要に応じて、表の主キーを定義します。

カスケード削除および外部キー制約

表を定義する際には、宣言カスケード削除または外部キー制約は使用しないでください。カスケード削除は分散データベース全体にわたっては機能しないため、必要な箇所すべてにカスケード削除ロジックを作成する必要があります。

参照整合性検査を実装するには、引数として表の一意キーを取り、行の削除により参照整合性エラーが発生する場合に例外を発生するPL/SQLストアド・プロシージャを作成します。

関連項目: 整合性チェック

LONG、LONG RAWおよびRAWデータ型

LONG、LONG RAWまたはRAWデータ型を使用した表の作成は避けてください。Oracle Forms内では、ワイルドカードを使用してこれらの型の列を検索することはできません。また、LONGおよびLONG RAW型の表列はオンライン・パッチ適用で使用できません。LONGのかわりにCLOB、RAWおよびLONG RAWのかわりにBLOBの列を使用してください。

LONGからCLOBへの変換プロシージャ

前述したように、Oracle E-Business Suiteリリース12.2では、LONGまたはLONG RAW型の表列は使用できません。オンライン・パッチ適用では、LONGおよびLONG RAW列をデータベース・トリガーで参照できません。この制限は、LONGおよびLONG RAW列をオンライン・パッチを使用してパッチできないことを意味します。これは、この機能がcrosseditionトリガーを使用してデータを更新するためです。実行エディションのシード・データに対する変更内容を同期するにはcrosseditionトリガーが使用されるため、変更内容はパッチ・エディションに伝播できません。

この項では、LONGからCLOBへ使用を変更するための変換プロシージャをいくつか説明します。

Oracle Forms

LONGからCLOBに変更された表列ごとに、列への参照があるフォーム・ブロック項目は、そのOracle Formsデータ型をCharからLongに変更する必要があります。CLOBはデータベース列型で、LongはFormsの項目データ型であることに注意してください。フォームのデータ型を変更するには、Forms Builderにフォームを開き、CLOBを参照する項目のプロパティ・シート(プロパティ・パレット)を開きます。

変更したフォーム項目への参照についてフォームおよびフォーム・ライブラリ・コードをスキャンします。フォーム項目はFormsのLongデータ型になっているため、LENGTH()、LENGTHB()、SUBSTR()などの関数は異なる動作をする可能性があります。FormsのLongデータ型を参照するロジックが機能するように、フォームを完全にテストしてください。

Pro*C / C

CLOBに変更するLONGまたはLONG RAWをバインドしている場合は、バインドをSQLT_LNGからSQLT_CLOBに変更する必要があります。そのようにしないと、不明なデータ型エラーがスローされます。

UPIコードを使用している場合は、RDBMSパッチ13259364を適用済であることを確認してください。

PL/SQL

すべてのパッケージをチェックして、影響を受けるすべての変数がLONGからCLOBに変更されていることを確認してください。

例(更新済の変数を使用):

PROCEDURE insert_flex_validation_events( flex_value_set_id IN NUMBER, event_code IN varchar2, user_exit IN CLOB) 
document_long_text CLOB;
document_long_text fnd_documents_long_text.long_text%type;

Java

JDBC 2.0および3.01では、列への参照を取得し、さらに文字入力ストリーム・オブジェクトを取得してCLOBフィールドの内容を並行して読み取るために、ResultSet.getClob()を使用してCLOB列からデータをフェッチする必要があります。Oracle Database 11g リリース2のJDBCドライバはCLOB用のgetString()を完全に実装しているため、プログラム変換は必要ありません。

Oracle Application Framework

BC4JおよびUIXデータ・バインドはデータ型の影響を大きく受けます。このため、データ型の変更によって影響を受ける問合せに対して、次の手順を実行することをお薦めします。

Oracle Application Framework開発の詳細は、Oracle Application Frameworkのマニュアルを参照してください。

予約語を使用した列

名前にPL/SQLまたはOracle Formsの予約語を含む列が表に存在する場合、列の名前を別名にするビューを表に作成する必要があります。このビューは他の表に結合しないため、挿入、更新および削除を通常どおり実行できます。

ビュー

一般に、複雑なブロックはビューに基づき、単純な設定のブロックは表に基づきます。ビューの使用には、次のような利点があります。

値リスト(LOV)をビューのベースにする必要があります。これにより、LOV定義を集中管理および共有できます。LOVビューには非正規化された列が少なく、有効なデータ行のみが含まれるため、LOVビューは通常ブロック・ビューよりも単純です。

関連項目: 値リストの例

パフォーマンス改善のためのビュー定義

パフォーマンスが問題になり、表に外部キーが含まれる場合、パフォーマンスを改善するためにビューを定義する必要があります。ビューにより、1つのSQL文が外部キーを処理することになり、サーバーによる解析が減少し、ネットワークの通信量が減少します。

モジュール性促進のためのビュー定義

データベースで使用可能なオブジェクトは、すべてのクライアントまたはサーバー側のコードからアクセスできるため、モジュール性および再利用が促進されます。ビューが必要とされる理由は次のとおりです。

ビューを作成しない場合

ビューを使用するSQL文が1つのみの場合、ビューの作成は避けてください。SQL文を含むコードとビューの両方を維持する必要があるため、1つのプロシージャのみが使用するビューを作成するとメンテナンスの負荷が増加します。

最初の列はROW_ID

ビューの最初の列としてルート表の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が指定されている順序は作成しないでください。順序の全範囲が広くなりすぎるため、上限に達することは現実的にはありえません。

通常は、ラップする順序、または範囲に制限のある順序は設計しないでください。

順序値を格納するNUMBERデータ型の使用

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_UNIQUE_IDENTIFIER_CONTROLは廃止されており、この製品ではオブジェクトに対して行は存在しません。

また、アプリケーション固有のFND表を作成してFND_UNIQUE_IDENTIFIER_CONTROL表と置き換えることも避けてください。

表登録API

AD_DDパッケージのPL/SQLルーチンを使用して、カスタム・アプリケーション表を登録します。

この情報に依存する機能または製品は、フレックスフィールド、Oracle AlertおよびOracle Web Applications Desktop Integratorのみです。したがって、フレックスフィールド、Oracle AlertまたはOracle Web Applications Desktop Integratorで使用する場合にのみ、表(および列すべて)を登録します。AD_DD APIは、後で表を変更する際に、Oracle Application Object Libraryの表からの表および列の登録削除にも使用できます。

後で表を変更する場合は、表登録ルーチンへの修正済または新規のコールを含める必要があります。登録を変更するには、まず登録を削除してから表または列を再登録します。最初に列の登録を削除し、次に表の登録を削除してください。

PL/SQLスクリプトに表登録ルーチンへのコールを含める必要があります。表は自分のアプリケーション・スキーマに作成しますが、APPSスキーマに対してAD_DDプロシージャを実行する必要があります。変更を反映させるには、変更をコミットします。

AD_DD APIは、データベース・スキーマに登録済の表または列が存在するかどうかはチェックせず、必要なFND表を更新するのみです。登録済の表および列が実際に存在し、AD_DD APIを使用して定義したものと同じ形式であるかを確認してください。ビューは登録する必要ありません。

AD_DDパッケージのプロシージャ

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 E-Business Suite製品のみで使用)。
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 E-Business Suite製品リリース用に変換される場合は「Y」を(Oracle E-Business Suite製品のみで使用)、変換されない場合は「N」を使用(ほとんどのアプリケーション列)。
p_next_extent 次エクステントのサイズ(単位はKB)。「K」を含めない。
p_precision 数値全体の桁数。
p_scale 数値の小数点以下の桁数。

AD_DDパッケージの使用例

フレックスフィールドの表とその列を登録する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');