最近のアクセス:
For Each コマンドにおける Data Selector

Data Selector を、For Each コマンドで使用する方法は、次の 2 とおりあります:
  1. Using 節
  2. Where 節における IN 演算子
これらのどちらの方法を使うかによって、Data Selector の定義にある項目属性が For Each コマンドのベーステーブルを特定するのに関与するかどうかが決まります。

1.Using 節

構文

For Each  [ <BaseTrn1>|<BaseTrn.Level1>,...,<BaseTrnN>|<BaseTrn.LevelN> ]    
    USING <DataSelectorName>( [ <parm1>,...,<parmN> ] ) 
      <MainCode> 
EndFor
構文の表記規則の表示

入力値の説明:
BaseTrnBaseTrn.Level1,...,BaseTrnBaseTrn.LevelN
       コンマ区切りのトランザクションまたは Transaction.Level の名前です。

DataSelectorName
      Data Selector の名前です。

parm1, …, parmN
      変数 (呼び先オブジェクトで定義) または項目属性です。

MainCode
      コマンドのリストです。

例 A

次のトランザクションがあるとします:
Customer 
{ 
CustomerId* 
CustomerName 
CustomerImage 
CustomerStatus 
}
「ActiveCustomers」Data Selector の定義は次のとおりです:
イメージ:51133.jpg
この Data Selector には、Active Customers を表示するために定義された条件があります。
その後、Procedure オブジェクト (または Web Panel オブジェクトなど) の [ Source ] で以下を定義して、Data Selector を呼び出すことができます。
For each Customer USING ActiveCustomers() 
   print printblock1 //printblock1 には次の項目属性を含む: CustomerId、CustomerName 
EndFor

例 B

次のトランザクションがあるとします:
Invoice 
{ 
InvoiceId* 
InvoiceNumber 
InvoiceDate 
}
InvoicesByDate という Data Selector を次のように定義します:
イメージ:51134.jpg
この 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 節を記述した場合と同じです。
イメージ:13238.jpg
ナビゲーションレポート: 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 の警告が示されます)。

2.Where 節における IN 演算子

構文

For Each  [ <BaseTrn1>|<BaseTrn.Level1>,...,<BaseTrnN>|<BaseTrn.LevelN> ]  
     Where  [ not ]  <attribute> IN <DataSelectorName>( [ <parm1>,...,<parmN>, … ] ) 
    <MainCode> 
EndFor
構文の表記規則の表示

入力値の説明:
BaseTrnBaseTrn.Level1,...,BaseTrnBaseTrn.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 を宣言でき、ほかのどのオブジェクトからでも呼び出せるということです。
イメージ:13240.jpg
ナビゲーションレポート: 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

動画

イメージ:20668.png Data Selectors


サブページ
Created: 14/09/18 03:16 by Admin Last update: 23/01/29 23:45 by Admin
カテゴリ
Powered by GXwiki 3.0