Data Selector を、
For Each コマンドで使用する方法は、次の 2 とおりあります:
- Using 節
- Where 節における IN 演算子
これらのどちらの方法を使うかによって、Data Selector の定義にある項目属性が For Each コマンドの
ベーステーブルを特定するのに関与するかどうかが決まります。
For Each [ <BaseTrn1>|<BaseTrn.Level1>,...,<BaseTrnN>|<BaseTrn.LevelN> ]
USING <DataSelectorName>( [ <parm1>,...,<parmN> ] )
<MainCode>
EndFor
構文の表記規則の表示
入力値の説明:
BaseTrn1 |
BaseTrn.Level1,...,BaseTrnN |
BaseTrn.LevelN
コンマ区切りのトランザクションまたは Transaction.Level の名前です。
DataSelectorName
Data Selector の名前です。
parm1, …, parmN
変数 (呼び先オブジェクトで定義) または項目属性です。
MainCode
コマンドのリストです。
次の
トランザクションがあるとします:
Customer
{
CustomerId*
CustomerName
CustomerImage
CustomerStatus
}
「ActiveCustomers」Data Selector の定義は次のとおりです:
この Data Selector には、Active Customers を表示するために定義された条件があります。
その後、Procedure オブジェクト (または Web Panel オブジェクトなど) の [ Source ] で以下を定義して、Data Selector を呼び出すことができます。
For each Customer USING ActiveCustomers()
print printblock1 //printblock1 には次の項目属性を含む: CustomerId、CustomerName
EndFor
次のトランザクションがあるとします:
Invoice
{
InvoiceId*
InvoiceNumber
InvoiceDate
}
InvoicesByDate という Data Selector を次のように定義します:
この Data Selector には日付の条件があり、InvoiceDate による順序が指定されています。
Web Panel オブジェクト (または Procedure オブジェクトなど) の [ Events ] で以下を定義して、Data Selector を呼び出すことができます。
For Each USING InvoicesByDate(&FromDate, &ToDate)
&InvoiceId = InvoiceId
&InvoideDate = InvoiceDate
EndFor
For Each 内で Using 節によって Data Selector を呼び出す場合、Data Selector には関連付けられたナビゲーションがありません (ベーステーブルがありません)。分析時には Data Selector の定義は For Each の定義と組み合わされ、両方の定義の項目属性を考慮してナビゲートされるテーブルが決定します。また、次にようになります:
- For Each および Data Selector の両方に条件がある場合、両方が考慮されます。
- For Each および Data Selector に Order 節がある場合、結果として得られる順序はこれらを組み合わせたものです。For Each の Order 節が優先され、Data Selector の Order 節が無視された場合は、仕様検証時に警告 spc0135 が発生します。
USING 節によって [ ActiveCustomers ] の Data Selector を呼び出す次の For Each があるとします。
For Each Using ActiveCustomers()
Where CountryName = "Uruguay"
...EndFor
これは分析時に展開されます:
For Each
Where CustomerStatus = "Active"
Where CountryName = "Uruguay"
...EndFor
注: 上の例のように For Each 内で Data Selector を呼び出した場合のパフォーマンスは、For Each 内に Where 節を記述した場合と同じです。
ナビゲーションレポート: Data Selector の詳細は記されていません。
ここで、For Each 文で、条件付き Order 節を複数と、条件なし Order 節 (default order) を 1 つ定義し、Using 節を使用して Data Selector を呼び出すとします。
For Each コマンドに default order 節を 1 つしか指定できないので、この場合の分析結果は、条件付き order 節 (複数) のある For Each、Data Selector の条件付き order 節、For Each の default order 節という形になります (Data Selector の default order 節が破棄され、ナビゲーションレポートに spc0135 の警告が示されます)。
For Each [ <BaseTrn1>|<BaseTrn.Level1>,...,<BaseTrnN>|<BaseTrn.LevelN> ]
Where [ not ] <attribute> IN <DataSelectorName>( [ <parm1>,...,<parmN>, … ] )
<MainCode>
EndFor
構文の表記規則の表示
入力値の説明:
BaseTrn1 |
BaseTrn.Level1,...,BaseTrnN |
BaseTrn.LevelN
For Each コマンドのベーストランザクション節と同じです。
Attribute
Data Selector ベーステーブルの拡張テーブルに属すことができる項目属性の名前です。
DataSelectorName
Data Selector の名前です。
parm1, …, parmN
変数 (呼び先オブジェクトで定義) または項目属性です。
MainCode
コマンドのリストです。
For Each
Where CustomerId IN InvoicesByDate(&FromDate,&ToDate)
...Endfor
For Each の Where 節で IN 演算子を指定して Data Selector を呼び出す場合は、Data Selector 自体の
ベーステーブルがなければなりません。したがって、Data Selector の定義で生成される SELECT 文は、For Each 用に生成される SELECT 文とは異なる独立したものになります。
GeneXus 15 Upgrade 5 までの場合、IN 演算子に先行する項目属性は、Data Selector のベーステーブルの拡張テーブルに属している必要があります。上の例では、
CustomerId は、INVOICE という拡張テーブルに属していますが、この拡張テーブルは InvoicesByDate Data Selector のベーステーブルです。
GeneXus 15 Upgrade 6 以降では、IN 演算子に関連付けられた項目属性は、必ずしも拡張テーブルに属している必要はありません。次の仕様は、Customer テーブルと Provider テーブルの間に関係がない場合に有効です。
For Each Where CustomerId In ProviderIds()
...EndFor
ProviderIds Data Selector の仕様は次のとおりです:
Defined by: ProviderId
Defined by 節の使い方に注目してください。結果の SQL 文は、Power テーブルと User テーブルの間に関係がない、次のようなものになります。
SELECT .....FROM [ Customer ] WITH
WHERE [ CustomerId ] IN (SELECT [ ProviderId ] FROM [ Provider ] )
Data Selector のクエリは、IN 演算子に先行する項目属性と同じ定義に対応する値のコレクションを返します。上の例では、Data Selector は任意の範囲内の請求書と顧客リストを返します。
つまり、For Each のベーステーブルは、For Each 項目属性のみを考慮して決定されます (Data Selector の項目属性は考慮されません)。For Each はその
ベーステーブルおよび
拡張テーブルをナビゲートし、Data Selector が返した顧客リストの顧客を含むレコードをフィルタリングします。
したがって、上の例では、左側で指定した項目属性が、Data Selector のベーステーブルの拡張テーブルに属する限り、目的の値が Data Selector によって返されることになります。ここで重要なのは、内部で行われる抽出の仕組みではなく、Data Selector を宣言でき、ほかのどのオブジェクトからでも呼び出せるということです。
ナビゲーションレポート: Data Selector の詳細は記されていません。
Data Selector の Order 節で指定したのは InvoiceDate ですが、ナビゲーションレポートに示されるのは CustomerId なので、疑問に思われるかもしれません。しかし、後者は、Each コマンドの order 節を示しています。一方、Data Selector は、InvoiceDate を介してテーブルにアクセスし、そのナビゲーションの詳細は、GeneXus では示されません。
Data Selector のナビゲーションは、For Each の選択肢の副選択肢として生成されます。そのため、Data Selector に独自の条件がある場合、これらの条件は DBMS によってサーバー内で評価する必要があります。これを考慮すると、次のエラー/警告が分析時に表示される場合があります。
- spc0053 Conditional constraint %1 cannot be generated in group starting at line n. Changed to standard constraint.
データセレクターに
条件付き制約が指定されている場合は、自動的に標準の制約に変更されます。
- spc0144 Condition %1 found in DataSelector %2 cannot be evaluated in server.
ただし、一部の
関数は、サーバーで評価できません。
IN 演算子では、IN 節の前の項目属性が考慮されます。複合キーを使用してフィルタする場合は、新しい冗長式項目属性を作成し、連結する必要があります。上の例を使用して、マルチテナントサポートを追加する場合、1 つの方法として、TenantId* (複合キー) 項目属性をすべてのテーブルの一部として追加することができます。
In 演算子を使用するには、フィルタを実行するための TenantIdCustomerId 冗長項目属性を作成する必要があります。
For Each
Where TenantIdCustomerId IN InvoicesByDate(&FromDate,&ToDate)
...Endfor
グリッドにおける Data Selector
集計における Data Selector
Data Provider における Data Selector
Data Selectors in Web Panels
Work With for Smart Devices の List ノード
Entry Panels as Filters for a List in Smart Devices
Data Selectors