制約の検証
はじめに
EBX® Scriptを使用すると、データモデルに検証制約を定義できます。制約は、ユーザーが有効で正確かつ論理的に一貫性のあるデータのみを入力するようにするデータモデル上のルールです。制約は、テーブル、レコード、テーブルフィールド、データセットフィールドなど、さまざまなレベルで定義できます。
制約が無効なデータを検出すると、検証レポートにカスタムメッセージを追加できます。メッセージテキストと重大度レベルを選択できます。
制約は、高度なコントロールビューのデータモデルアシスタント (DMA)で作成します。EBX®は、コンテキストに応じたコード補完を提供するEBX® Script IDEで編集できる初期スクリプトを生成します。
制約内のローカライズされたユーザーメッセージを管理するには、EBX®スクリプトAPIのcore.messageを使用します。このAPIは、検証レポートにユーザーフレンドリーなメッセージを作成および追加するためのいくつかのメソッドを提供します。
初期スクリプト
構造
制約の初期スクリプトは次の構造を持ちます。
<unit usage statement 1>
<unit usage statement 2>
...
<unit usage statement N>
export procedure constraint_signature_name()
begin
...
<statement 1>
<statement 2>
...
end
export procedure setup()
begin
...
<statement 1>
...
end
次のスクリプト例は、部署内の従業員に対する制約を示しています。従業員番号が100未満であるかどうかをチェックします。100未満の場合、検証レポートのコンテキストに警告メッセージが追加されます。
export procedure checkRecord(record : .Department)
begin
if (record.Number < 100i) then
begin
var message:='The employee number of the department '|record.Name |' is under 100';
msg.addWarning(message);
end
end
export procedure setup()
begin
// Initialization can be added here
...
end
エクスポートされたプロシージャ
EBX®は、制約を評価する際にエクスポートされたプロシージャを直接呼び出します。各制約スクリプトは、そのタイプに関連するエクスポートされたプロシージャのみを宣言できます(制約タイプに応じて2つまたは3つのプロシージャ)。エクスポートされたプロシージャ setup( ) は必須です。EBX®は、制約コンテキストを初期化するためにこれを呼び出します。制約の依存関係の宣言など、初期化タスクを実行するために使用します。
EBX®には次の制約タイプが含まれています。
-
テーブルに対する制約: テーブル全体が特定の条件を満たすことを保証するためのテーブルレベルのチェックを定義します。また、レコードが特定の条件を満たすことを保証するためのレコードレベルのチェックの定義も可能です。
-
フィールドに対する制約: フィールドが特定の条件を満たすことを保証するためのフィールドレベルのチェックを定義します。
-
Nullに対する制約: フィールドが必須であり、Nullであってはならないことを保証するためのフィールドレベルのチェックを定義します。制約プロシージャのシグネチャは次のとおりです。
-
checkTable( ) および checkRecord( ) : 制約タイプがテーブルに対する制約の場合に呼び出されます。
-
check( ) : 制約タイプがフィールドに対する制約の場合に呼び出されます。
-
checkNull( ) : 制約タイプがNullに対する制約の場合に呼び出されます。
-
setup( ) : 制約を初期化するために呼び出されます。このプロシージャは、すべての制約タイプで必須です。
注: エクスポートされたプロシージャのシグネチャ(名前)は制約のタイプに依存するため、変更しないでください。エクスポートされたプロシージャ setup( ) は必須であり、変更しないでください。
事前定義変数
事前定義変数を使用すると、制約コンテキストで利用可能な情報にアクセスできます。制約タイプに応じて、次の事前定義変数を使用できます。
データセット
事前定義変数 \_ebx.dataset は、現在のデータセットに関する情報へのアクセスを提供します。これは、すべてのEBX® Scriptの使用法(トリガー、関数フィールドなど)に共通の事前定義変数です。詳細については、リファレンスセクションを参照してください。また、すべての制約タイプで利用可能です。
例:
uses core.message as msg;
// This constraint adds information about the name of the current dataset.
export procedure checkTable()
begin
msg.adInfo('The dataset name is: ' | _ebx.dataset.name);
end
export procedure setup()
begin
...
end
データスペース
事前定義変数 \_ebx.dataspace は、現在のデータスペースへの読み取りアクセスを許可します。これは、すべてのスクリプトの使用法(トリガー、関数フィールドなど)に共通の事前定義変数です。詳細については、リファレンスを参照してください。また、すべての制約タイプで利用可能です。
例:
uses core.message as msg;
// This constraint adds information about the name of the current dataspace.
export procedure check()
begin
msg.addInfo('The dataspace name is: ' | _ebx.dataspace.name);
end
export procedure setup()
begin
...
end
ルート
事前定義変数 \_ebx.root は、データセットの現在のルートへの読み取り専用アクセスを提供します。これはすべての制約タイプで利用可能です。ルート下のフィールドは、現在のEBX®スキーマによって定義されます。
例:
uses core.message as msg;
// This constraint adds information about the reference code.
export procedure check()
begin
msg.addInfo('Reference code '|_ebx.root.code);
end
export procedure setup()
begin
...
end
制約タイプ
検証制約は、データモデル内のデータの一貫性を確保するための特定のルールを定義します。これは、データモデルのさまざまなレベル(テーブル、レコード、またはフィールド)に適用できます。検証制約が違反された場合、ユーザー定義の重大度レベルを持つカスタマイズされたエラーメッセージを検証レポートに追加できます。以下に、さまざまなレベルでの検証制約の例を示します。
テーブルに対する制約
テーブルレベルのチェック
この制約タイプはテーブル全体をチェックし、エラーが検出された場合にメッセージを追加します。テーブル全体が一度にチェックされます。SQLクエリとXPath式を使用して、チェックする特定のレコードを選択できます。
例:
uses core.message as msg;
export procedure checkTable()
begin
// This constraint checks the customers with an empty address and adds an error message.
// A localized user message ('The address is mandatory.') is created from a resource bundle.
var userMessage:= msg.ofBundleError('bundle1/path1','address.mandatory');
// Adds an error message for each customer with an empty address.
msg.addXPathMessage('osd:is-empty(Address)',userMessage);
end
export procedure checkRecord(record :.Employee)
begin
end
export procedure setup()
begin
...
end
レコードレベルのチェック
この制約は、テーブルレベルのチェックに加えて、レコードレベルのチェックをサポートします。特定のレコードに対するカスタム検証を定義できます。これにより、ユーザーがデータを入力したり、レコードを変更したりする際のエラーを検出するのに役立ちます。
checkRecord メソッドの record パラメーターは、現在のレコードへの読み取り専用アクセスを提供します。これは、制約タイプ テーブルに対する制約 のレコードレベルチェックで利用可能です。レコードのフィールドは、現在のEBX®スキーマによって定義されます。
例 1:
uses core.string as str;
uses core.message as msg;
export procedure checkRecord(record :.Employee)
begin
// This constraint checks if the email ends with tibco.com and adds a warning message if not.
if (not(str.endsWith(record.Email,'tibco.com'))) then
begin
msg.addWarning('The email '|record.Email |' should end with tibco.com');
end
end
end
export procedure setup()
begin
...
end
例 2:
uses core.message as msg;
export procedure checkTable()
begin
end
export procedure checkRecord(record : .Product)
begin
// This constraint checks if the price of the product is under a threshold.
if (record.Price < _ebx.root.PriceThreshold) then
begin
var message:='The price of the product '|record.Price |' is under the threshold '|_ebx.root.PriceThreshold;
msg.addWarning(message);
end
end
export procedure setup()
begin
...
end
フィールドに対する制約
この制約タイプはフィールドレベルのチェックを定義します。フィールドが特定の条件を満たすことを保証します。フィールドが無効な場合、ローカライズされたメッセージを追加できます。この制約タイプは、データセットフィールドまたはテーブルフィールドに定義できます。
データセットフィールドレベルのチェック
この制約タイプは、データセットフィールドレベルのチェックを定義します。他のデータセットフィールドにアクセスするには、事前定義変数 \_ebx.root を使用します。
例:
uses core.message as msg;
export procedure check()
begin
// This constraint checks if the image height is between 150 and 500.
if (_ebx.root.image.height > 150 and _ebx.root.image.height < 500) then
begin
// add a warning message
var message:='Image height should be between 150 and 500. Current height is '|_ebx.root.image.height;
msg.addWarning(message);
end
end
export procedure setup()
begin
...
end
テーブルフィールドレベルのチェック
この制約タイプは、テーブルフィールドレベルのチェックを定義します。テーブル内の各レコードに対してフィールドが特定の条件を満たすことを保証します。フィールドが無効な場合、ローカライズされたメッセージを追加できます。変数 record は check() のパラメーターとして渡されます。これは、現在のフィールドを含むレコードへの読み取り専用アクセスを提供します。
例:
uses core.message as msg;
// This constraint checks if the project's completed tasks are under 10 and adds an info message
export procedure check(record : .Project)
begin
if (record.Number < 10) then
begin
msg.addInfo('Completed tasks is under 10'|record.ProjectId);
end
end
export procedure setup()
begin
end
Nullに対する制約
この制約タイプは、フィールドが値を含むかどうかをデータセットまたはテーブルフィールドレベルでチェックします。フィールドがNullの場合、メッセージを追加できます。
データセットフィールドレベルのチェック
例:
uses core.message as msg;
// This constraint adds an error message if the project code is missing.
export procedure checkNull()
begin
//Add a message from a bundle with one parameter: 'The code of the project {0} is mandatory'
var message:= msg.ofBundleError('bundle1/path1','project.code.mandatory',_ebx.root.project.name);
msg.addMessage(message);
end
export procedure setup()
begin
...
end
テーブルフィールドレベルのチェック
例:
uses core.message as msg;
// This constraint checks that the publication year is present for the Book.
// If the publication year is missing, an error message is added to the validation report.
export procedure checkNull(record : .Book)
begin
msg.addError('Publication year is mandatory');
end
export procedure setup()
begin
end
制約の依存関係
制約の検証結果は、特定のフィールドの更新、挿入、または削除に依存する場合があります。これらの場合、制約の初期化中にフィールドの依存関係を明示的に宣言できます。制約の依存関係を宣言することで、検証プロセス中の制約への呼び出し回数を最小限に抑えることができます。
依存関係を指定する必要はありません。ただし、明示的な依存関係は、大量のデータを検証する場合や、検証ロジックが高コストである場合にパフォーマンスを向上させます。
EBX® Script APIのcore.validationは、制約の依存関係を宣言するためのいくつかのメソッドを提供します。
警告: 計算値または継承されたフィールドに対する依存関係は指定できません。
挿入、削除、および変更の依存関係
制約の検証結果は、指定されたフィールドの挿入、変更、および削除に依存します。
例:
uses core.validation as v;
export procedure checkTable()
begin
...
end
export procedure checkRecord(record :.Product)
begin
...
end
export procedure setup()
begin
// Declare that this constraint depends on the current record's 'Price' and 'Quantity' fields.
v.addDependencyToInsertDeleteAndModify('/root/Product/Price');
v.addDependencyToInsertDeleteAndModify('/root/Product/Quantity');
end
挿入および削除の依存関係
制約の検証結果は、指定されたテーブルの挿入および削除に依存します。
例:
uses core.validation as v;
export procedure checkTable()
begin
...
end
export procedure checkRecord(record : .Customers)
begin
...
end
export procedure setup()
begin
// Declares that this constraint depends on the 'Orders' table.
v.addDependencyToInsertAndDelete('/root/Orders');
end
変更の依存関係
制約の検証結果は、指定されたフィールドの値に依存します。
例:
uses core.message as msg;
uses core.validation as v;
export procedure check()
begin
...
end
export procedure setup()
begin
// Declares that this constraint depends on modification of the code field.
v.addDependencyToModify('/root/Code');
end
別のデータセットへの依存関係
制約の検証結果は、指定されたデータセットおよびデータスペース内の指定されたフィールドまたはテーブルの挿入、変更、および削除に依存します。
例:
uses core.validation as v;
export procedure checkTable()
begin
...
end
export procedure checkRecord(record : .Customers)
begin
...
end
export procedure setup()
begin
// Declare that this constraint depends on the 'Status' field of another dataset and dataspace.
v.addDependencyToInsertAndDeleteAndModifyInOtherDataset("/root/Orders/Status", 'otherDataset', 'otherDataspace');
v.addDependencyToInsertAndDeleteInOtherDataset('/root/Items','otherDataset','otherDataspace');
end