标识符(实体 SQL)

实体 SQL 中使用标识符来表示查询表达式别名、变量引用、对象的属性、函数等。 实体 SQL 提供两种类型的标识符:简单标识符和带引号的标识符。

简单标识符

实体 SQL 中的简单标识符是字母数字字符和下划线字符序列。 标识符的第一个字符必须是字母字符(a-z 或 A-Z)。

带引号的标识符

带引号的标识符是括在方括号([])中的任何字符序列。 带引号的标识符允许使用标识符中无效的字符指定标识符。 方括号之间的所有字符都将成为标识符的一部分,包括所有空格。

带引号的标识符不能包含以下字符:

  • 换行符。

  • 回车符。

  • 制表符。

  • Backspace。

  • 其他方括号(即方括号内的方括号,用于描述标识符)。

带引号的标识符可以包含 Unicode 字符。

使用带引号的标识符可以创建在标识符中无效的属性名称字符,如以下示例所示:

SELECT c.ContactName AS [Contact Name] FROM customers AS c

还可以使用带引号的标识符来指定一个标识符,该标识符是实体 SQL 的保留关键字。 例如,如果类型 Email 具有名为“From”的属性,则可以使用方括号将其从保留关键字 FROM 中消除歧义,如下所示:

SELECT e.[From] FROM emails AS e

可以在点 (.) 运算符的右侧使用带引号的标识符。

SELECT t FROM ts as t WHERE t.[property] == 2

若要在标识符中使用方括号,请添加额外的方括号。 在以下示例“abc]”中,标识符为:

SELECT t from ts as t WHERE t.[abc]]] == 2

有关带引号的标识符比较语义,请参阅 输入字符集

别名规则

建议根据需要在实体 SQL 查询中指定别名,包括以下 Entity SQL 构造:

  • 行构造函数的字段。

  • 查询表达式的 FROM 子句中的项。

  • 查询表达式的 SELECT 子句中的项。

  • 查询表达式的 GROUP BY 子句中的项。

有效别名

实体 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 …

作用域规则

实体 SQL 定义范围规则,用于确定特定变量在查询语言中何时可见。 某些表达式或语句引入了新名称。 范围规则确定可以使用这些名称的位置,以及具有与另一个名称相同的新声明何时或何处可以隐藏其前置任务。

在实体 SQL 查询中定义名称时,它们据说在范围内定义。 范围涵盖查询的整个区域。 特定范围内的所有表达式或名称引用都可以看到在该范围内定义的名称。 在作用域开始和结束之前,不能引用在作用域内定义的名称。

范围可以嵌套。 Entity SQL 的某些部分引入了涵盖整个区域的新范围,这些区域可以包含其他也引入范围的实体 SQL 表达式。 嵌套范围时,可以对最内层范围中定义的名称(包含引用)进行引用。 还可以对任何外部作用域中定义的任何名称进行引用。 在同一范围内定义的任何两个范围都被视为同级范围。 不能对同级范围内定义的名称进行引用。

如果在内部作用域中声明的名称与在外部作用域中声明的名称匹配,则内部作用域内或在该范围内声明的范围内声明的引用仅引用新声明的名称。 外部作用域中的名称处于隐藏状态。

即使在同一范围内,在定义名称之前也不能引用这些名称。

全局名称可以作为执行环境的一部分存在。 这可以包括永久性集合或环境变量的名称。 若要使名称成为全局名称,必须在最外部的范围内声明它。

参数不在范围内。 由于对参数的引用包括特殊语法,因此参数名称永远不会与查询中的其他名称冲突。

查询表达式

实体 SQL 查询表达式引入了新的范围。 FROM 子句中定义的名称按外观顺序引入范围,从左到右。 在联接列表中,表达式可以引用前面在列表中定义的名称。 FROM 子句中标识的元素的公共属性(字段等)不会添加到 from-scope 中。 它们必须始终由别名限定的名称引用。 通常,SELECT 表达式的所有部分都在范围内考虑。

GROUP BY 子句还引入了新的同级范围。 每个组可以有一个组名称,该组引用组中元素的集合。 每个分组表达式还将新名称引入组范围。 此外,嵌套聚合(或命名组)也会添加到范围。 分组表达式本身位于范围内。 但是,使用 GROUP BY 子句时,select-list(投影)、HAVING 子句和 ORDER BY 子句被视为在组范围内,而不是从范围。 聚合接收特殊处理,如以下项目符号列表所述。

以下是有关范围的其他说明:

  • select-list 可以按顺序将新名称引入范围。 右侧的投影表达式可能引用左侧投影的名称。

  • ORDER BY 子句可以引用在选择列表中指定的名称(别名)。

  • SELECT 表达式中子句的计算顺序决定了名称引入范围的顺序。 首先计算 FROM 子句,后跟 WHERE 子句、GROUP BY 子句、HAVING 子句、SELECT 子句,最后计算 ORDER BY 子句。

聚合处理

实体 SQL 支持两种形式的聚合:基于集合的聚合和基于组的聚合。 基于集合的聚合是实体 SQL 中的首选构造,支持基于组的聚合实现 SQL 兼容性。

解析聚合时,Entity SQL 首先尝试将其视为基于集合的聚合。 如果失败,Entity SQL 会将聚合输入转换为对嵌套聚合的引用,并尝试解析此新表达式,如以下示例所示。

AVG(t.c) becomes AVG(group..(t.c))

另请参阅