SELECT 函数

SELECT 函数组合、过滤和转换复杂消息和数据库数据。

语法

注:
  1. SELECT 表达式中不再要求使用方括号。 不过这并不阻止您使用方括号,但如果有方括号,它们也只是作为用来限制表达式作用域的普通方括号。
  2. 您只能为 COUNT 参数将以下 Expression 指定为一个星号(*)。

用途

SELECT 函数是用来转换消息的最常用、最高效方法。您可以使用 SELECT:
  • 全面地重新格式化消息
  • 访问数据库表
  • 制作输出数组,它是输入数组的子集
  • 制作输出数组,它仅包含输入数组的值
  • 计算数组中的条目数
  • 从数组的许多条目中选择最小值或最大值
  • 计算数组中各值的和

SELECT 简介

与数据库表不同,SELECT 函数使用消息树(或子树)包含大量“行”和“列”。FROM 子句中的 FieldReference 标识消息树中的字段,并且:
  • 标识的字段被视为表中的“行”。
  • 字段的同代被视为同一个“表”中的其他“行”。
  • 字段的子代被视为表的“列”。
注: FROM 子句中的 FieldReference 也可以是表引用,它直接引用实际的数据库表。

SELECT 函数的返回值通常是另一个包含“行”的消息树,行的结构和内容由 SelectClause 决定。结果中的行数是 FROM 子句中经过 WHERE 子句过滤后所有字段引和表引用指向的所有“行”的总和;其中只包含 WHERE 子句求值结果为 TRUE 的字段。

SELECT 函数的返回值也可以是标量(请参阅 ITEM 选择)。

您可以通过多种方法指定 SelectClause;请参阅:

简单的选择语句

要更详细地了解 SELECT 函数,请首先参阅一个简单的例子,其中:
  • SelectClause 由许多表达式构成,每个表达式都带有 Path 子句。
  • FROM 子句包含一个 FieldReference 和一个 AS CorrelationName 子句。
SELECT 函数创建局部、引用、相关变量,其名称由 AS CorrelationName 子句指定,然后这些变量单步遍历从 FROM 子句派生的行列表中的每一“行”。对于每一“行”:
  1. 相关变量设置为指向当前“行”。
  2. 对 WHERE 子句(如果存在的话)求值。如果求值结果是 FALSE 或未知(NULL),则不向结果树添加任何内容,处理继续到输入的下一“行”。否则处理将继续到下一步。
  3. 向结果列表添加新成员。
  4. 对 SELECT 子句表达式求值,并将该值赋予 AS Path 子句指定的字段。这些字段是结果列表中新成员的子代字段。

SelectClause 和 WHERE 子句表达式通常都使用相关变量访问“列”值(即,输入消息树中的字段),以便构建新消息树,用于包含来自输入消息的数据。AS CorrelationName 子句中指定的名称引用相关变量,或者,如果未指定 AS 子句,则由 FROM FieldReference 中最后的名称(即,最后一个点后的名称)引用相关变量。

注意:
  • 尽管与表有一定的类似,但并不限制您只使用类似表的平面结构来访问或创建消息;您可以访问和构建带有任意深度的文件夹结构的树。
  • 并不限制您只使用作为单个值的“列”;列可以是重复列表值或结构。
通过参考示例可以最深入地理解这些概念。

如果字段引用实际上是 TableReference,操作就非常相似。在这种情况下,输入内容是实际的数据库表,因此就只限使用数据库支持的平面结构。但结果树仍不是这样限制。

如果 FROM 子句中有多个字段引用,最右边的引用将单步遍历右起第二个引用中的每一行,依此类推。这样,结果中的总行数就是每个表中行数的乘积。这种选择被称为连接,通常使用 WHERE 子句从结果中将这些行中的大多数排除出去。连接通常用于将数据库数据添加到消息中。

AS Path 子句是可选的。如果未指定它,代理会根据以下规则生成缺省名称:
  1. 如果 SelectClause 表达式是对字段的引用,或是对字段引用的强制类型转换,则使用该字段的名称。
  2. 否则代理将使用缺省名称“Column1”、“Column2”等。

示例

以下示例对数据库“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 选择

INSERT 子句是 AS 子句的备用子句。它将 SelectClause 表达式的结果(必须是行)赋给当前的新行自身,而不是赋给它的子代。这样做的效果是将表达式的行结果合并到 SELECT 生成的行中。它与 AS 子句的区别是:AS 子句在添加结果前总是至少生成一个子代元素,而 INSERT 不生成子代元素。从其他 SELECT 操作插入数据时,INSERT 很有用,因为它允许合并数据,而无需额外的文件夹。

ITEM 选择

SelectClause 可以由关键字 ITEM 和一个表达式构成。它的作用是使结果没有名称。即,结果是一列由表达式返回的类型值,而不是行。此选项有多种用途:
  • 与标量表达式和 THE 函数结合使用时,它可以用于创建返回单个标量值(例如,表中特定物品的价格)的 SELECT 查询。
  • 与 CASE 表达式和 ROW 构造函数结合使用时,它可以用于创建 SELECT 查询,该查询创建或处理某些“行”(即,在消息中重复)的结构与其他行不同的消息。这对于处理具有重复结构但重复部分并非结构完全相同的消息非常有用。
  • 与 ROW 构造函数结合使用时,它可以用于创建 SELECT 查询,以折叠输入消息中的重复级别。

列函数选项

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 表达式

SelectClause
SelectClause 表达式可以使用任何代理运算符和函数的任意组合。这些表达式可以引用表列、消息字段、通过包含 SELECT 声明的相关名以及作用域中声明的任何其他变量或常量。
AS Path
AS Path 表达式是相对路径(即,没有相关名),但不受任何方式的限制。例如,它可以包含:
  • 下标(例如,A.B.C[i])
  • 字段型说明符(例如,A.B.(XML.Attribute)C)
  • 多段式路径(例如,A.B.C)
  • 名称表达式(例如,A.B.{var})

这些路径中的所有表达式也可以使用任何代理运算符和函数的任意组合。这些表达式可以引用表列、消息字段、通过包含 SELECT 声明的相关名,以及声明的任何变量或常量。

FROM 子句
FROM 子句表达式可以包含多个数据库引用、多个消息引用或两者的混合。您可以将表与表、消息与消息或表与消息连接在一起。

FROM 子句 FieldReference 可以包含任何种类的表达式(例如,Database.{DataSource}.{Schema}.Table1)。

您可以在运行时计算字段、数据源、模式或表名。

WHERE 子句

WHERE 子句表达式可以使用代理的任何运算符和函数的任何组合。这些表达式可以引用表列、消息字段以及任何声明的变量或常量。

但是,代理检查 WHERE 子句表达式并确定整个表达式是否能被数据库求值来处理该表达式。如果可以,就将此表达式交给数据库。为了能被数据库求值,表达式必须只使用数据库支持的函数和运算符。

但是,WHERE 子句可以引用消息字段、通过包含 SELECT 声明的相关名以及作用域中的任何其他声明的变量或常量。

如果整个表达式无法由数据库进行求值,则代理查找顶级 AND 运算符并分别检查每个子表达式。然后代理尝试将数据库可以求值的子表达式交给数据库,把其他子表达式留给自己求值。由于以下两个原因,您需要了解这种情况:
  1. WHERE 子句表达式的微小更改显然可以对性能造成很大影响。您可以通过检查用户跟踪信息决定把多少表达式交给数据库。
  2. 某些数据库函数的行为与代理函数的行为有细微的差别。

与 THE 函数的关系

您可以将函数 THE(它返回列表的第一个元素)与 SELECT 结合使用以产生非列表结果。这种结合很有用,例如,当要求 SELECT 查询返回的项不超过一个时。它与 ITEM 结合使用时也特别有用(请参阅 ITEM 选择)。

与 SQL 标准的区别

ESQL SELECT 在以下几个方面与数据库 SQL SELECT 不同:
  • ESQL 可以生成树型结构的结果数据
  • ESQL 在 SELECT 子句中可以接受数组
  • ESQL 具有 THE 函数以及 ITEM 和 INSERT 参数
  • ESQL 在此发行版上没有 SELECT ALL 函数
  • ESQL 在此发行版上没有 ORDER BY 函数
  • ESQL 在此发行版上没有 SELECT DISTINCT 函数
  • ESQL 在此发行版上没有 GROUP BY 或 HAVING 参数
  • ESQL 在此发行版上没有 AVG 列函数

局限性

以下局限性适用于当前发行版:
  • 当 SELECT 命令操作多个数据库表时,所有表必须在同一数据库实例中。(即,TableReference 不可指定其他数据源名称。)
  • 如果 FROM 子句既引用消息又引用表,在列表中表必须在消息前面。
相关概念
ESQL 概述
相关任务
正在开发 ESQL
转换简单 XML 消息
转换复杂 XML 消息
在 XML 消息中返回标量值
从 ESQL 访问数据库
相关参考
语法图:可用类型
复杂 ESQL 函数
声明 | 商标 | 下载 | 书库 | 支持 | 反馈
Copyright IBM Corporation 1999, 2006 最后一次更新时间:2006/08/14
ak05620_