識別子 (Entity SQL)
識別子はクエリ式の別名、変数参照、オブジェクトのプロパティ、関数などを表すために Entity SQL で使用されます。 Entity SQL の識別子には、単純な識別子と引用符で囲まれた識別子の 2 種類があります。
単純な識別子
Entity SQL の単純な識別子は、英数字とアンダースコア文字のシーケンスです。 識別子の最初の文字は英文字 (a ~ z または A ~ Z) にする必要があります。
引用符で囲まれた識別子
引用符で囲まれた識別子とは、角かっこ ([]) で囲まれた文字のシーケンスです。 引用符で囲まれた識別子を使用すると、単純な識別子内では無効になる文字を使用して識別子を指定することができます。 角かっこ内のすべての文字 (すべての空白文字を含む) が識別子の一部になります。
ただし、次の文字を含めることはできません。
改行
キャリッジ リターン
タブ
バックスペース
追加の角かっこ (識別子の境界を表す角かっこの中の角かっこ)
Unicode 文字を含めることはできます。
引用符で囲まれた識別子を使用することにより、次の例のように、識別子では無効な文字を含むプロパティ名を作成できます。
SELECT c.ContactName AS [Contact Name] FROM customers AS c
また、Entity SQL の予約済みキーワードを識別子として指定することもできます。 たとえば、Email
型に "From" という名前のプロパティがある場合、次のように角かっこを使用することで、予約済みキーワードの FROM と区別できます。
SELECT e.[From] FROM emails AS e
ドット (.) 演算子の右側に引用符で囲まれた識別子を使用できます。
SELECT t FROM ts as t WHERE t.[property] == 2
識別子に角かっこを使用するには、角かっこをもう 1 つ追加します。 次の例では、"abc]
" が識別子です。
SELECT t from ts as t WHERE t.[abc]]] == 2
引用符で囲まれた識別子の比較セマンティクスについては、「入力文字セット」をご覧ください。
別名の規則
Entity SQL のクエリでは、次の Entity SQL コンストラクトなど、必要な場合は常に別名を指定することをお勧めします。
行コンストラクターのフィールド
クエリ式の FROM 句の項目
クエリ式の SELECT 句の項目
クエリ式の GROUP BY 句の項目
有効な別名
Entity SQL での有効な別名は、単純な識別子および引用符で囲まれた識別子です。
別名の生成
Entity SQL のクエリ式で別名が指定されていない場合、Entity SQL では次の単純な規則に基づいて別名が生成されます。
クエリ式 (別名が指定されていないクエリ式) が単純な識別子または引用符で囲まれた識別子の場合は、その識別子が別名として使用されます。 たとえば、
ROW(a, [b])
がROW(a AS a, [b] AS [b])
になります。より複雑なクエリ式でも、最後の構成要素が単純な識別子であれば、その識別子が別名として使用されます。 たとえば、
ROW(a.a1, b.[b1])
がROW(a.a1 AS a1, b.[b1] AS [b1])
になります。
後に使用する別名に対しては暗黙的な別名を使用しないことをお勧めします。 別名 (暗黙的な別名または明示的な別名) が同じスコープで競合していたり繰り返し使用されていたりするとコンパイル エラーが発生しますが、 暗黙的な別名は、同じ名前の明示的または暗黙的な別名があってもそのままコンパイルされます。
暗黙的な別名は、ユーザー入力に基づいて自動的に生成されます。 たとえば次のコードでは、両方の列の別名として NAME が生成されるため、競合が発生します。
SELECT product.NAME, person.NAME
明示的な別名を使用している次のコードも同じように失敗しますが、 こちらの方がコードを見たときにエラーを発見しやすくなります。
SELECT 1 AS X, 2 AS X …
スコープの規則
Entity SQL ではスコープの規則が定義されています。これにより、クエリ言語で特定の変数をいつ参照できるかが決まります。 一部の式やステートメントでは新しい名前が導入されます。 スコープの規則は、そのような名前をどこで使用でき、いつ (どこで) 同じ名前の新しい宣言によって前の名前を参照できなくなるのかが決まります。
Entity SQL のクエリで名前を定義すると、それらはスコープの中で定義されたことになります。 スコープはクエリの全領域をカバーします。 特定のスコープで定義されている名前は、そのスコープのすべての式や名前参照から参照できます。 スコープが始まる前や終わった後では、そのスコープで定義されている名前は参照できません。
スコープは入れ子にすることもできます。 Entity SQL の一部では、領域全体をカバーする新しいスコープが導入され、これらの領域には、やはりスコープが導入される他の Entity SQL の式を含めることができます。 スコープが入れ子になっている場合、最も内側のスコープに含まれている参照からは、そのスコープで定義されている名前を参照できるだけでなく、 それより外側のスコープで定義されている名前も参照できます。 同じスコープ内で定義されている 2 つのスコープは兄弟スコープと見なされます。 兄弟スコープで定義されている名前を参照することはできません。
内側のスコープで宣言した名前が外側のスコープで宣言されている名前と一致する場合、内側のスコープ内の参照や、そのスコープの中で宣言したスコープ内の参照は、その新しく宣言した名前のみを参照します。 外側のスコープの名前は参照できません。
同じスコープの中であっても、まだ定義されていない名前を参照することはできません。
グローバルな名前は実行環境の一部として存在することができます。 たとえば、永続的なコレクションや環境変数の名前がこれに含まれます。 名前をグローバルにするには、最も外側のスコープで宣言する必要があります。
パラメーターはスコープに含まれません。 パラメーターの参照には特別な構文が含まれるため、パラメーターの名前がクエリ内の他の名前と衝突することはありません。
クエリ式
Entity SQL のクエリ式では、新しいスコープが導入されます。 FROM 句で定義された名前は、出現順 (左から右の順) に from スコープに導入されます。 結合リストでは、既にリストで定義されている名前を式で参照できます。 FROM 句で指定された要素のパブリック プロパティ (フィールドなど) は from スコープに追加されません。 それらは常に、別名で修飾された名前で参照する必要があります。 通常は、SELECT 式のすべての部分が from スコープに含まれると見なされます。
GROUP BY 句でも新しい兄弟スコープが形成されます。 各グループは、そのグループ内の要素のコレクションを参照するグループ名を持つことができます。 各グループ化式も、group スコープに新しい名前を導入します。 さらに、入れ子集計 (名前付きグループ) もスコープに追加されます。 グループ化式自体は from スコープに含まれますが、 選択リスト (投影)、HAVING 句、および ORDER BY 句は、GROUP BY 句が使用されている場合には from スコープではなく group スコープに含まれると見なされます。 集計は、この後で説明するように特別扱いになります。
スコープに関する追加の注意事項を以下に示します。
選択リストでは、新しい名前が順番にスコープに導入されます。 右側の投影式では、左側で投影されている名前を参照できます。
ORDER BY 句では、選択リストで指定されている名前 (別名) を参照できます。
SELECT 式内の句が評価される順序によって、名前がスコープに導入される順序が決まります。 FROM 句が最初に評価され、WHERE 句、GROUP BY 句、HAVING 句、SELECT 句の順に続き、最後に ORDER BY 句が評価されます。
集計の処理
Entity SQL では、コレクションベースの集計とグループベースの集計の 2 つの形式の集計がサポートされています。 Entity SQL ではコレクションベースの集計を使用することをお勧めします。グループベースの集計は、SQL との互換性のためにサポートされています。
Entity SQL では、集計を解決するとき、まずコレクション ベースの集計として処理することが試みられます。 それが失敗した場合、Entity SQL では、参照へのその集計入力が入れ子集計に変換されて、この新しい式の解決が試みられます。以下に例を示します。
AVG(t.c) becomes AVG(group..(t.c))