最近のアクセス:
For Each コマンドにおける複数のベーストランザクション

複数For Each コマンドを使用して表現するのが難しい、複数テーブルをナビゲートするクエリを解決する必要がある場合、または単一の SQL 文では解決できないクエリの場合、For Each コマンドに複数のベーストランザクションを追加することができます。
これは、For Each コマンドベーストランザクション節を使用する場合に見られる例です。

構文

for each <トランザクション 1> {, <トランザクション i>}...
<メインのコード>
endfor
入力値の説明:
<トランザクション i>: トランザクションまたはレベルの名前です (つまり <トランザクション i>.<レベル名>)。
<メインのコード>: ベーストランザクションのテーブルの、結合されたレコードまたはデカルト積内の各レコードに対して実行されるコードです。テーブル (TRN1、TRN2、...、TRNm) が直接関連付けられている場合 (または、2 つの異なる項目属性間の同等性によって明示的なフィルタを定義する場合)、それらのトランザクションレベルに関連付けられているテーブル間で結合が行われます。そうでない場合は、デカルト積が行われます。また、関連付けが見つからない場合は、分析エラーが発生します (spc0027)。

注: 結合の種類は、関連する項目属性に null 値を使用できるかどうかに応じて決まります。いずれかに null 値を使用できる場合、結合は外部結合になり、それ以外の場合は内部結合になります。

例 I

複数の企業で構成されるシステムで、各企業 (Company) が製品を販売し、各プロバイダー (Provider) がそれらの製品を提供しているとします。
構造は次のようになります:
Product
{
   ProductId*
   ProductName
}

Company
{
   CompanyId*
   CompanyName
}

Provider
{
   ProviderId*
   ProviderName
}

ProdCompany
{
   CompanyId*
   ProductId*
}

ProviderProduct
{
   ProviderId*
   ProductId*
}
このようなシナリオで、特定の会社が販売する製品と、特定のプロバイダーが供給する製品すべてのリストが必要だとします。この場合のクエリは、For Each コマンド内でベーストランザクション節を使用して複数のベーストランザクションを宣言しないかぎり、1 つの For Each コマンドのみを使用して解決できない可能性があります。
For Each ProdCompany, ProviderProduct
   Where CompanyId  = 1
   Where ProviderId = 2
   Print ProductInfo  //printblock: ProductName 項目属性
Endfor
例: 次のデータにおいて CompanyId = 1 および ProviderId = 2 でフィルタすると、P1 と P4 が表示されます:
イメージ:24665.jpg
次に示すのは、前のコードに対応するナビゲーションです:
イメージ:24467.png
この例での SQL 文 (SQL Server 用) は次のようになります。ProductId 項目属性を使用して結合が行われていることに注意してください:
SELECT T1. [ ProductId ] , T3. [ ProviderId ] , T1. [ CompanyId ] , T2. [ ProductName ]  FROM (( [ ProdCompany ]  T1 WITH (NOLOCK) INNER JOIN  [ Product ]  T2 WITH (NOLOCK) ON T2. [ ProductId ]  = T1. [ ProductId ] ) INNER JOIN  [ ProviderProduct ]  T3 WITH (NOLOCK) ON T3. [ ProductId ]  = T1. [ ProductId ] ) WHERE (T1. [ CompanyId ]  = 1) AND (T3. [ ProviderId ]  = 2) ORDER BY T1. [ CompanyId ] 
注: 前述の例を解決するもう 1 つの方法として、ヒントとしてのフィルタを検討してください。
同じシナリオで、同じ製品を販売する会社とプロバイダーの組み合わせのリストが必要だとします。それを解決するコードは次のとおりです:
For Each ProdCompany, ProviderProduct
   Print CompanyAndProviderNames //printblock: CompanyName、ProviderName 項目属性
Endfor
また、特定の製品を販売する会社とプロバイダーの組み合わせのリストが必要だとします。
For Each ProdCompany, ProviderProduct
   Where ProductId = &ProductId
   Print CompanyAndProviderNames //printblock: CompanyName、ProviderName 項目属性
Endfor

例 II

トランザクション構造は次のとおりです:
Transaction1
{
  A*
  B  
  C  
}

Transaction2
{
  D*
  E
}
B と D の間に関係がない場合に (それぞれ名前が異なり、サブタイプではない)、For each を次のように定義するとします:
For each Transaction1 ,Transaction2
  where B = D
   print printblock1 //printblock: C および E 項目属性
endfor
Transaction1 と Transaction2 はベーストランザクションとして宣言され、B および D 項目属性間の同等性によって明示的フィルタが定義されると、Transaction1 と Transaction2 に関連付けられているテーブル間で結合が行われます。
この例での SQL 文 (SQL Server 用) は次のように生成されます。
SELECT T2.D, T1.B, T1.C, T2.E, T1.A FROM Transaction1 T1,  Transaction2 T2 WHERE T1.B = T2.D ORDER BY T1.A.
前述の例は、複数のベーストランザクションを宣言する節を使用しないかぎり、単一の For Each コマンドを使用して解決できないことに注意してください。


例 III

通常、テーブルのデカルト積のリストを作成する必要はありませんが、このリストが必要な場合に GeneXus で For Each コマンドを使用してモデルを構築するのは困難です。
For Each コマンドのベーストランザクション節を使用すると、これを非常に直観的な方法で実行できます。
トランザクション構造は次のとおりです。
User
{
   UserId*
   UserName
   UserType
}

Program
{
   ProgramId*
   ProgramName
}
管理者ユーザー (すべてのプログラムへのアクセス許可を持つ) でフィルタリングした、User テーブルおよび Program テーブルのデカルト積のリストが必要だとします。複数のベーストランザクション節を For Each コマンド内で使用すると、コードは次のようになります:
For Each User, Program
   Where UserType = 'Administrator'
   Print UserAndProgramNames  //printblock: UserName、ProgramName 項目属性
Endfor






サブページ
Created: 15/01/07 22:49 by Admin Last update: 21/05/21 03:32 by Admin
カテゴリ
Powered by GXwiki 3.0