WHERE 節の定義式
最も一般的なタイプの WHERE 節の定義式は SearchCondition です。ただし、ほかの定義式も使用できます。以下の API では、WHERE 節の定義式をサポートしています。
appendWhere(WhereExpression a_expression, int[] a_fromIndicies)
appendWhere(WhereExpression a_expression, TableExpression[] a_tableExpressions, String[] a_aliases)
以下に、具象的な WhereExpression の実装を示します。
SearchCondition
|
このクラスは、照会のサーチ条件を表します。QuerySpec に追加すると、この値が SQL WHERE 節で使用されます。
|
ExistsExpression
|
このクラスは、WHERE 節の EXSISTS 定義式を表します。StatementSpec インスタンスが副問い合わせに使用されます。
|
CompositeWhereExpression
|
このクラスは論理演算子 (AND/OR) を使用して接続される WHERE 定義式の数を表します。
|
NegatedExpression
|
このクラスは、WHERE 節の定義式の否定を表します。この定義式の値が求められると、このクラスに先頭に NOT が付いた総計 WhereExpression が格納されます。
|
fromIndices パラメータを使用して、WHERE 定義式のオペランドを FROM 節のテーブルに関連付けます。appendSelect() メソッドと同様に、fromIndices 配列は WhereExpression のタイプとそれらの WhereExpressions で使用する ColumnExpressions に基づいています。たとえば、ClassAttribute と ConstantExpression を含む SearchCondition には、インデックスが 1 つ必要です。3 つの SearchConditions を含む CompositeWhereExpression では、各 SearchCondition で必要なサイズの合計と同じサイズの fromIndices 配列が必要です。
以下の例では、fromIndices の正しい使用方法について説明します。このコードによって部品とそれらに関連する代替部品を照会します。以下に CompositeWhereExpression の使用に関する基準をいくつか示します。関連する部品番号の 2 番目から 4 番目までの文字は同じです。部品の名前は "E" で始まり、代替部品の名前は "E" で始まります。コードの最初のセクションで、照会内のクラス、選択アイテム、およびクラス間の結合が設定されます。
QuerySpec qs = new QuerySpec();
int partIndex = qs.appendClassList(wt.part.WTPartMaster.class, false);
int alternatePartIndex = qs.appendClassList(wt.part.WTPartMaster.class, false);
int linkIndex = qs.appendClassList(wt.part.WTPartAlternateLink.class, false);
// Define the attributes in the query
ClassAttribute partName =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NAME);
ClassAttribute alternatePartName =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NAME);
ClassAttribute partNumber =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NUMBER);
ClassAttribute alternatePartNumber =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NUMBER);
// Define constants used in the criteria
ConstantExpression subStringStart = new ConstantExpression(new Long(2));
ConstantExpression subStringEnd = new ConstantExpression(new Long(4));
ConstantExpression wildcardExpression = new ConstantExpression("E% [ ]");
// Add items to the select and join the classes
qs.appendSelect(partName, new int[] { 0 }, false);
qs.appendSelect(alternatePartName, new int[] { 1 }, false);
qs.appendJoin(linkIndex, wt.part.WTPartAlternateLink.ALTERNATES_ROLE, partIndex);
qs.appendJoin(linkIndex, wt.part.WTPartAlternateLink.ALTERNATE_FOR_ROLE,
alternatePartIndex);
以下のセクションでは、基準を作成し、照会に追加します。最初の SearchCondition では ClassAttribute インスタンスを 2 つ使用します。対応するインデックスを appendWhere で使用される fromIndices 配列に追加する必要があります。同様に、2 番目の SearchCondition は部品クラスを参照し、3 番目の SearchCondition は代替部品クラスを参照します。そのため、fromIndices が 4 つ必要になり、各配列要素は適切な SearchCondition に対応する必要があります。
CompositeWhereExpression orExpression =
new CompositeWhereExpression(LogicalOperator.OR);
orExpression.append(new SearchCondition(
SQLFunction.newSQLFunction(SQLFunction.SUB_STRING,
partNumber, subStringStart, subStringEnd),
SearchCondition.EQUAL,
SQLFunction.newSQLFunction(SQLFunction.SUB_STRING,
alternatePartNumber, subStringStart, subStringEnd)));
orExpression.append(new SearchCondition(
partName, SearchCondition.LIKE, wildcardExpression));
orExpression.append(new SearchCondition(
alternatePartName, SearchCondition.LIKE, wildcardExpression));
qs.appendWhere(orExpression, new int[] {
partIndex, alternatePartIndex, partIndex, alternatePartIndex });
最後の API では、WHERE 定義式のオペランドのテーブル定義式とエイリアスを明示的に指定します。この API は相関副問い合わせで使用されます。副問い合わせを使用する場合は、一般に、相関コラム (外部選択のコラムと副問い合わせのコラム間の結合) を使用します。これは、TableExpressions およびエイリアスが明示的に渡される appendWhere() API を使用する場合にサポートされます。副問い合わせを含まない WhereExpressions の場合は、QuerySpec FROM 節と指定のインデックスにより、TableExpressions およびエイリアスが暗黙的に派生します。
以下の例は、EXISTS 節および相関副問い合わせを使用した照会です。照会からは、代替の PartMaster が存在しないすべての PartMasters が返されます。代替は、WTPartAlternateLink クラスを使用して表します。これは、PartMasters 間の多対多の関係です。WTPartAlternateLink クラスの役割 A は現在の PartMaster を指定し、B は代替の PartMaster を指定します。以下に、この照会の SQL を示します。
SELECT A0.*
FROM WTPartMaster A0
WHERE NOT (EXISTS (SELECT B0.ida2a2
FROM WTPartAlternateLink B0
WHERE (A0.ida2a2 = B0.ida3a5)))
以下のコードで、照会の仕様を作成します。外部選択により、PartMaster オブジェクトが返されます。
QuerySpec select = new QuerySpec();
int partIndex = select.appendClassList(wt.part.WTPartMaster.class, true);
以下のコードで、副問い合わせを作成します。エイリアスのプリフィックスを変更して外部選択との競合を回避します。
QuerySpec subSelect = new QuerySpec();
subSelect.getFromClause().setAliasPrefix("B");
int altIndex = subSelect.appendClassList(wt.part.WTPartAlternateLink.class,
false);
subSelect.appendSelect(new ClassAttribute(
wt.part.WTPartAlternateLink.class, WTAttributeNameIfc.ID_NAME),
new int[] { altIndex }, true);
以下のコードで、TableExpressions およびエイリアスを明示的に設定します。これらは配列として渡されます。結合は外部選択から副問い合わせに対して実行されるので、外部選択の値を配列のインデックス 0 に配置し、副問い合わせの値を配列のインデックス 1 に配置します。次に、これらの配列を使用して、SearchCondition を追加します。
TableExpression[] tables = new TableExpression[2];
String[] aliases = new String[2];
tables[0] = select.getFromClause().getTableExpressionAt(partIndex);
aliases[0] = select.getFromClause().getAliasAt(partIndex);
tables[1] = subSelect.getFromClause().getTableExpressionAt(altIndex);
aliases[1] = subSelect.getFromClause().getAliasAt(altIndex);
SearchCondition correlatedJoin = new SearchCondition(
wt.part.WTPartMaster.class, WTAttributeNameIfc.ID_NAME,
wt.part.WTPartAlternateLink.class,WTAttributeNameIfc.ROLEA_OBJECT_ID);
subSelect.appendWhere(correlatedJoin, tables, aliases);
最後に、否定の EXISTS 節を外部選択に追加します。
select.appendWhere(new NegatedExpression(new
ExistsExpression(subSelect)), null);