SELECT 函数组合、过滤和转换复杂消息和数据库数据。
SELECT 函数的返回值通常是另一个包含“行”的消息树,行的结构和内容由 SelectClause 决定。结果中的行数是 FROM 子句中经过 WHERE 子句过滤后所有字段引和表引用指向的所有“行”的总和;其中只包含 WHERE 子句求值结果为 TRUE 的字段。
SELECT 函数的返回值也可以是标量(请参阅 ITEM 选择)。
SelectClause 和 WHERE 子句表达式通常都使用相关变量访问“列”值(即,输入消息树中的字段),以便构建新消息树,用于包含来自输入消息的数据。AS CorrelationName 子句中指定的名称引用相关变量,或者,如果未指定 AS 子句,则由 FROM FieldReference 中最后的名称(即,最后一个点后的名称)引用相关变量。
如果字段引用实际上是 TableReference,操作就非常相似。在这种情况下,输入内容是实际的数据库表,因此就只限使用数据库支持的平面结构。但结果树仍不是这样限制。
如果 FROM 子句中有多个字段引用,最右边的引用将单步遍历右起第二个引用中的每一行,依此类推。这样,结果中的总行数就是每个表中行数的乘积。这种选择被称为连接,通常使用 WHERE 子句从结果中将这些行中的大多数排除出去。连接通常用于将数据库数据添加到消息中。
以下示例对数据库“DSN1”内模式“Shop”中的表“Parts”执行 SELECT。由于没有 WHERE 子句,因此选中所有行。由于选择子句表达式(例如,P.PartNumber)不包含 AS 子句,因此结果中的字段采用相同的名称:
SET PartsTable.Part[] = SELECT P.PartNumber, P.Description, P.Price FROM Database.DSN1.Shop.Parts AS P;
如果 SET 语句的目标(“PartsTable”)是 ROW 类型的变量,该语句执行后,对于表中的每一行,PartsTable 将具有一个名为“Part”的字段作为其根元素的子代。每个“Part”字段将具有名为“PartNumber”、“Description”和“Price”的子字段。这些子字段将具有表的内容表示的值。(“PartsTable”也可以引用到消息树中)。
下一个示例执行类似的 SELECT。这种情况与 SELECT 在第一个示例生成的消息树上(而不是实际数据库表上)执行的最后一种情况不同。它将结果赋予“OutputRoot”的子文件夹:
SET OutputRoot.XML.Data.TableData.Part[] = SELECT P.PartNumber, P.Description, P.Price FROM PartsTable.Part[] AS P;
INSERT 子句是 AS 子句的备用子句。它将 SelectClause 表达式的结果(必须是行)赋给当前的新行自身,而不是赋给它的子代。这样做的效果是将表达式的行结果合并到 SELECT 生成的行中。它与 AS 子句的区别是:AS 子句在添加结果前总是至少生成一个子代元素,而 INSERT 不生成子代元素。从其他 SELECT 操作插入数据时,INSERT 很有用,因为它允许合并数据,而无需额外的文件夹。
SelectClause 可以包含表达式中运行的函数 COUNT、MAX、MIN 和 SUM 之一。这些函数称为列函数。它们返回单个标量值(而不是列表),提供 Expression 在单步遍历 FROM 子句的各行时计算出的计数、最大值、最小值或总值。对于某个特定行,如果 Expression 的求值结果为 NULL,则忽略该值,以便函数返回其余行的计数、最大值、最小值或总值。
只有 COUNT 函数的 Expression 可以由单个星号(*)构成。不管行中是否有 NULL 值,该格式都对行进行计数。
为使结果真实反映输入消息,Expression 通常包含相关变量。
Expression 通常对每一行中的相同数据类型求值。在这些情况下,MAX、MIN 和 SUM 函数的结果类型与操作数的数据类型相同。但返回值没必要全部属于同一种类型,如果它们属于不同类型,则应用一般的算法规则。例如,如果重复消息结构中的字段某些行是整数值,其他行是浮点值,则按照一般的加法规则求和。由于此运算相当于将许多整数和浮点值相加,因此结果将是浮点型。
COUNT 函数的结果始终是整数。
用相关变量表示消息中行的 FROM 表达式与用相关变量表示实际数据库表中行的表达式略有不同。
对于消息表达式,包含星号(*)的路径具有普通含义;它忽略字段的名称,并查找匹配其他标准(如果有的话)的第一个字段。
SELECT * FROM Database.Datasource.SchemaName.Table As A SELECT A.* FROM Database.Datasource.SchemaName.Table As A SELECT A FROM Database.Datasource.SchemaName.Table AS A
这些路径中的所有表达式也可以使用任何代理运算符和函数的任意组合。这些表达式可以引用表列、消息字段、通过包含 SELECT 声明的相关名,以及声明的任何变量或常量。
FROM 子句 FieldReference 可以包含任何种类的表达式(例如,Database.{DataSource}.{Schema}.Table1)。
您可以在运行时计算字段、数据源、模式或表名。
WHERE 子句表达式可以使用代理的任何运算符和函数的任何组合。这些表达式可以引用表列、消息字段以及任何声明的变量或常量。
但是,代理检查 WHERE 子句表达式并确定整个表达式是否能被数据库求值来处理该表达式。如果可以,就将此表达式交给数据库。为了能被数据库求值,表达式必须只使用数据库支持的函数和运算符。
但是,WHERE 子句可以引用消息字段、通过包含 SELECT 声明的相关名以及作用域中的任何其他声明的变量或常量。
您可以将函数 THE(它返回列表的第一个元素)与 SELECT 结合使用以产生非列表结果。这种结合很有用,例如,当要求 SELECT 查询返回的项不超过一个时。它与 ITEM 结合使用时也特别有用(请参阅 ITEM 选择)。