複数のテーブル間での結合 (JOIN) を伴う For Each コマンド (X Evolution 2) (またはグリッドなど) が使用される場面では、GeneXus は自動的に結合の種類 (Join Type)、つまり、テーブル間で結合がどのように実装されるか (自然結合または外部結合) を判断します。また、データベースサーバーまたはアプリケーションサーバーのどちらで解決可能であるか (Join Location = 結合の場所) も判定します。
結合の種類 (Join Type) は、外部キーを構成する項目属性が Null 許容かどうかに基づいて設定されます。外部キーが Null 許容の場合、外部 (または左) 結合が行われます。Null 許容でない場合は、自然 (または内部) 結合が使用されます。
ナビゲーションレポートには、自然結合の場合は「=」(等号)、外部結合の場合は「~」が表示されます (後出の例を参照してください)。
- 結合がアプリケーションサーバーで解決される場合、結合の種類は必ず外部結合 ( [ Join Type ] = Outer Join) になります。
- 互換性維持のため、[ Join Type ] プロパティが用意されています。
For Each コマンド (またはグリッドなど) に伴う結合は、生成されるオブジェクトのロジックにしたがって、データベースサーバー (DBMS) またはクライアント (アプリケーションサーバー) のいずれかで「解決」できます。この情報は、ナビゲーションレポートで [ Join Location: client | server ] のように表示されます。
一般に、パフォーマンス上の理由からサーバーでの解決が試みられますが、次のような例外もあります:
- ナビゲーションに関与するテーブルが別のデータストアに属している場合
- VFP DBF の使用時
- Update を実行する For Each コマンドがある場合で、以下の条件に該当するときは、結合がサーバーで解決されます:
- 内部結合で、DBMS が SQL Server、MySQL、Oracle、または PostgreSQL である (DB2 および Informix の場合は、クライアントで解決されます)
- 外部結合で、DBMS が MySQL である (それ以外の場合は、クライアントで解決されます)
複数のテーブルが結合されていて、2 つ以上のテーブルがデータベースサーバーで結合されている場合、Join Location はサーバーになります。
例
次のようなトランザクションについて検討してみましょう:
City
{
CityId*
CityName
}
Customer
{
CustomerId*
CustomerName
CityId (Nullable = No)
}
この 2 つのテーブルを結合する For Each がある場合:
For Each CustomerName CityName
...
Endfor
ナビゲーション詳細は次のようになります。
City テーブルを読み込むときのアイコンに注目してください (Natural Join)。
一方、顧客に都市が割り当てられていなくてもよいという設定になっている (Customer の CityId 外部キーの [ Nullable ] プロパティが Yes に設定されている) 場合、テーブル間の結合は外部結合になります:
いずれの場合も、サーバーで結合が実行されます。
|