最近のアクセス:
For Each コマンドにおけるデータセレクター

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

1. Using 節



構文

For Each  [ <BaseTrn1>|<BaseTrn.Level1>,...,<BaseTrnN>|<BaseTrn.LevelN> ]  
    USING <DataSelectorName>( [ <parm1>,...,<parmN> ] )
      <MainCode>
EndFor
構文の表記規則の表示
入力値の説明: BaseTrn1 | BaseTrn.Level1,...,BaseTrnN | BaseTrn.LevelN
コンマ区切りのトランザクションまたは Transaction.Level の名前です。
DataSelectorName
データセレクターの名前です。
parm1, …, parmN
変数 (呼び先オブジェクトで定義) または項目属性です。
MainCode
コマンドのリストです。


例 A

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


例 B

次のトランザクションがあるとします:
Invoice
{
InvoiceId*
InvoiceNumber
InvoiceDate
}
InvoicesByDate というデータセレクターを次のように定義します:
イメージ:51134.jpg
このデータセレクターには日付の条件があり、InvoiceDate による順序が指定されています。
Web Panel オブジェクト (または Procedure オブジェクトなど) の [ Events ] で以下を定義して、データセレクターを呼び出すことができます:
For Each USING InvoicesByDate(&FromDate, &ToDate)
      &InvoiceId = InvoiceId
      &InvoideDate = InvoiceDate
EndFor


考慮事項

For Each 内で Using 節によってデータセレクターを呼び出す場合、データセレクターには関連付けられたナビゲーションがありません (ベーステーブルがありません)。仕様解析時にはデータセレクターの定義は For Each の定義と組み合わされ、両方の定義の項目属性を考慮してナビゲートされるテーブルが決定します。また、次にようになります:
  • For Each およびデータセレクターの両方に条件がある場合、両方が考慮されます。
  • For Each およびデータセレクターに Order 節がある場合、結果として得られる順序はこれらを組み合わせたものです。For Each の Order 節が優先され、データセレクターの Order 節が無視された場合は、仕様解析時に警告 spc0135 が発生します。
USING 節によって「ActiveCustomers」データセレクターを呼び出す次の For Each があるとします:
For Each Using ActiveCustomers()
    Where CountryName = "Uruguay"
          ...
EndFor 
これは仕様解析時に展開されます:
For Each 
    Where CustomerStatus = "Active"
    Where CountryName = "Uruguay"
          ...
EndFor


注: 上の例のように For Each 内でデータセレクターを呼び出した場合のパフォーマンスは、For Each 内に Where 節を記述した場合と同じです。
イメージ:13238.jpg
ナビゲーションレポート: データセレクターの詳細は記されていません。
ここで、For Each 文で、条件付き Order 節を複数と、条件なし Order 節 (default order) を 1 つ定義し、Using 節を使用してデータセレクターを呼び出すとします。For Each コマンドには default order 節を 1 つしか指定できないので、この場合の仕様解析結果は、条件付き order 節 (複数) のある For Each、データセレクターの条件付き order 節、For Each の default order 節という形になります (データセレクターの default order 節が破棄され、ナビゲーションレポートに spc0135 の警告が示されます)。

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



構文

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
データセレクターのベーステーブルの拡張テーブルに属すことができる項目属性の名前です。
DataSelectorName
データセレクターの名前です。
parm1, …, parmN
変数 (呼び先オブジェクトで定義) または項目属性です。
MainCode
コマンドのリストです。

For Each
    Where CustomerId IN InvoicesByDate(&FromDate,&ToDate)
          ...
Endfor


考慮事項

For Each の Where 節で IN 演算子を指定してデータセレクターを呼び出す場合は、データセレクター自体のベーステーブルがなければなりません。したがって、データセレクターの定義で生成される SELECT 文は、For Each 用に生成される SELECT 文とは異なる独立したものになります。
GeneXus 15 Upgrade 5 までの場合、IN 演算子に先行する項目属性は、データセレクターのベーステーブルの拡張テーブルに属している必要があります。上の例では、CustomerId は、INVOICE という拡張テーブルに属していますが、この拡張テーブルは InvoicesByDate データセレクターのベーステーブルです。GeneXus 15 Upgrade 6 以降では、IN 演算子に関連付けられた項目属性は、必ずしも拡張テーブルに属している必要はありません。次の仕様は、Customer テーブルと Provider テーブルの間に関係がない場合に有効です。
For Each Where CustomerId In ProviderIds()
    ...
EndFor
ProviderIds データセレクターの仕様は次のとおりです:
Defined by: ProviderId
Defined by 節の使い方に注目してください。結果の SQL 文は、Power テーブルと User テーブルの間に関係がない、次のようなものになります。
SELECT..... FROM  [ Customer ]  WITH
WHERE  [ CustomerId ]  IN (SELECT  [ ProviderId ]  FROM  [ Provider ] )
データセレクターのクエリは、IN 演算子に先行する項目属性と同じ定義に対応する値のコレクションを返します。上の例では、データセレクターは任意の範囲内の請求書と顧客リストを返します。
つまり、For Each のベーステーブルは、For Each 項目属性のみを考慮して決定されます (データセレクターの項目属性は考慮されません)。For Each はそのベーステーブルおよび拡張テーブルをナビゲートし、データセレクターが返した顧客リストの顧客を含むレコードをフィルタリングします。
したがって、上の例では、左側で指定した項目属性が、データセレクターのベーステーブルの拡張テーブルに属する限り、目的の値がデータセレクターによって返されることになります。ここで重要なのは、内部で行われる抽出の仕組みではなく、データセレクターを宣言でき、ほかのどのオブジェクトからでも呼び出せるということです。
イメージ:13240.jpg
ナビゲーションレポート: データセレクターの詳細は記されていません。
データセレクターの Order 節で指定したのは InvoiceDate ですが、ナビゲーションレポートに示されるのは CustomerId なので、疑問に思われるかもしれません。しかし、後者は、Each コマンドの order 節を示しています。一方、データセレクターは、InvoiceDate を介してテーブルにアクセスし、そのナビゲーションの詳細は、GeneXus では示されません。

詳細な注記:

データセレクターのナビゲーションは、For Each の選択肢の副選択肢として生成されます。そのため、データセレクターに独自の条件がある場合、これらの条件は 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 Provider における Data Selector

動画

イメージ:20668.png Data Selectors



サブページ
Created: 14/09/18 03:16 by Admin Last update: 24/12/16 19:57 by Admin
カテゴリ
Powered by GXwiki 3.0