ESQL 字段引用

本主题描述如何使用 ESQL 字段引用来构成到消息体元素的路径。

字段引用的完整语法如下所示:

字段引用由后跟零个或多个以点(.)分隔的路径字段的相关名称组成。相关名指示众所周知的起点,必须是常量名、已声明的变量(标量行或引用)或某个预定义起点;例如,InputRoot。路径字段定义了起点至所需字段的路径。

例如:
InputRoot.XML.Data.Invoice
使代理从位置 InputRoot(即,Compute 节点的输入消息的根)开始,然后执行浏览序列。首先,它从根浏览到第一个子字段 XML,然后浏览到 XML 字段的第一个子字段 Data。最后,代理浏览到 Data 字段 Invoice 的第一个子字段。每当在 ESQL 程序中出现该字段引用时,将访问 invoice 字段。
这种形式的字段引用是简单方便的,且是最常用的。但是,它有两个局限性:
  • 因为使用的名称必须是有效的 ESQL 标识,您只能使用遵从 ESQL 规则的名称。也就是,名称只能包含字母数字字符(包括下划线),第一个字符不能为数字,且名称的长度必须至少为一个字符。可通过不符合这些规则的名称包含在双引号中来避免这些限制。例如:
    InputRoot.XML."Customer Data".Invoice
    如果您需要引用包含引号的字段,请在引用上使用两对引号。例如:
    Body.Message."""hello"""

    某些标识作为关键字保留,但除了相关名,您可以在字段引用中使用它们,而无需使用双引号

  • 因为字段的名称出现在 ESQL 程序中,编写程序时,它们必须是已知的。可通过使用花括号("{ ... }")的备用语法来避免此限制。此语法允许您使用任何返回类型为字符的非空值的表达式。
    例如:
    InputRoot.XML."Customer Data".{'Customer-' || 
    	CurrentCustomer}.Invoice
    其中,invoice 包含在名称由将字符文字“Customer-”和“CurrentCustomer”(此示例中,它必须是类型为字符的声明的变量)中的值连接而形成的文件夹中。

在路径元素中,您可以使用星号(*)通配符来匹配任何名称。也可以使用“*”来指定部分名称。例如,Prefix* 匹配以“Prefix”开始的任何名称。

注意,在 ESQL 中,将任何东西包含在双引号中,使它成为标识;将任何东西包含在单引号中,使它成为字符文字。必须把所有的字符串包含在单引号标记中。

请参阅:
  • 名称空间,以了解不同名称空间和名称组合的含义
  • 目标字段引用,以了解不同字段引用组合的含义
  • 索引,以了解不同索引子句组合的含义
  • 类型,以了解不同类型组合的含义

名称空间

字段名称可以属于名称空间。字段引用提供名称空间支持,如下所示:
  • 包含名称子句的每个字段引用的每个字段也可以包含定义指定的名称属于的名称空间的名称空间子句。
  • 每个名称空间名称可通过使用简单标识或表达式(包含在花括号中)来定义。如果标识是声明的名称空间常量,则将使用该常量的值。如果使用的是表达式,它必须返回类型为字符的非空值。
  • 名称空间子句 * 显式声明在树中定位字段时将忽略名称空间信息。
  • 不带标识、表达式或 * 的名称空间子句,即,只存在“:”,显式地表示目标为“notarget”名称空间

索引

字段引用的每个字段都可以包含一个索引子句。这些子句使用方括号([ ... ])表示,且接受任何返回类型为整数的非空值的表达式。这个子句标识要选择哪些带有相同名称的字段。字段从第一个(从 1 开始)开始编号。如果不存在这个子句,则假设需要的是第一个字段。因此,下面的两个示例具有完全相同含义:
InputRoot.XML.Data[1].Invoice
InputRoot.XML.Data.Invoice[1] 
此构造最常见的用法是与索引变量一起使用,这样循环将经过这样的字段。例如:
WHILE count < 32 DO
          SET TOTAL = TOTAL + InputRoot.XML.Data.Invoice[count].Amount;
     SET COUNT = COUNT + 1
END WHILE;
小心使用这种类型的构造,因为它暗示每次经过循环的开头,代理必须计数字段。如果重复计数很大,性能将降低。在这样的情况下,更好的替换方法是使用字段引用变量。
可以在索引表达式前面加上一个小于号(“<”),表明必需的字段将从最后一个字段(而不是第一个)开始建立索引。在这种情况下,索引 1 引用最后一个字段,索引 2 引用倒数第二个字段。为了保持完整性,可使用大于号来表明从第一个字段进行计数。以下示例显示了处理索引的 ESQL 代码,其中有四个名为“Invoice”的字段。
InputRoot.XML.Data.Invoice       -- Selects the first
InputRoot.XML.Data.Invoice[1]    -- Selects the first
InputRoot.XML.Data.Invoice[>]    -- Selects the first
InputRoot.XML.Data.Invoice[>1]   -- Selects the first
InputRoot.XML.Data.Invoice[>2]   -- Selects the second
InputRoot.XML.Data.Invoice[<]    -- Selects the fourth
InputRoot.XML.Data.Invoice[<1]   -- Selects the fourth
InputRoot.XML.Data.Invoice[<2]   -- Selects the third
InputRoot.XML.Data.Invoice[<3] -- Selects the second
索引子句也可由空方括号对([])组成。它会选择具有匹配名称的所有字段。使用这种具有需要您提供列表的函数和语句的构造(例如,SELECT、CARDINALITY、SINGULAR 和 EXISTS 函数,或 SET 语句)

类型

字段引用的每个字段都可以包含一个类型子句。这些子句使用括号(())表示,且接受任何返回类型为整数的非空值的表达式。类型表达式的存在限制字段选择为匹配类型的字段。该结构最常用于一般 XML,其中有许多字段类型,并且一个 XML 字段可能包含属性和带有相同名称的子 XML 字段。

例如:
<Item Value = '1234' >
     <Value>5678</Value>
</Item>

此处,XML 字段项有两个子字段,名称都是“Value”。可通过使用类型子句来区分子字段:使用 Item.(<Domain>.Attribute)Value 选择属性,使用 Item.(XML.Element)Value 选择字段,其中 <Domain> 是 XML、XMLNS 或 XMLNSC,这由源代码的消息域确定。

类型约束

类型约束检查字段引用返回的数据类型。
注:
  1. ScalarDataTypeName 可以是 BOOLEAN、INTEGER、INT、FLOAT、DECIMAL、DEC、DATE、TIME、TIMESTAMP、GMTTIME、GMTTIMESTAMP、INTERVAL、CHARACTER、CHAR、BLOB 或 BIT。

通常,类型约束会抽取引用的标量值(抽取方法与 FIELDVALUE 函数类似),如果引用类型不正确,则会抛出异常。根据定义,由于不存在的字段相当于 NULL,因此会对这些字段抛出异常。这在消息中缺少重要字段时提供了一个快速便捷导致异常的方法。

但是,当要被传递到数据库(例如,在 WHERE 子句中)的表达式中出现类型约束时,该信息用于确定表达式是否可以提供给数据库。如果 WHERE 子句在数据库表列上包含一个 CAST 操作,则这可能会很重要。如果缺少类型约束,则这样的表达式无法提供给数据库,因为代理无法告之数据库是否能够执行所需的约束。但是请注意:您在对列值使用类型强制转换操作时应该始终很小心,因为某些数据库具有非常有限的数据约束能力。

摘要

*, *[..], (..)*, (..)*[..]
这些格式都没有指定名称或名称空间。目标字段能以任意名称空间或无名称空间的形式拥有任何名称。它仅使用其类型、索引进行定位。或者在合适的地方,也可以使用其类型和索引进行定位。
NameId, NameId[..], (..)NameId, (..)NameId[..]
所有这些格式指定名称但不指定名称空间。目标字段使用名称空间和名称进行定位。在合适的地方,也可以使用类型和索引进行定位。

该名称空间是名称空间路径中唯一包含该名称的名称空间。路径中唯一的名称空间是 notarget 名称空间。

这些格式都存在于引入名称空间之前。尽管因为它们目前在同时比较名称和名称空间而使其行为发生了改变,但现有转换行为中应该没有改变,因为所有现有转换将在 notarget 名称空间中创建它们的字段。

: *, :*[..], (..):*, (..):*[..]
所有这些格式指定 notarget 名称空间但不指定名称。目标字段使用其名称空间进行定位。在合适的地方,也可以使用类型和索引进行定位。
: NameId, :NameId[..], (..):NameId, (..):NameId[..]
所有这些格式指定名称和 notarget 名称空间。可以按名称空间和名称查找目标字段,适当的情况下,也可以按类型和索引查找。
* :*, *:*[..], (..)*:*, (..)*:*[..]
这些格式都没有指定名称或名称空间。注意:“*:*”等于“*”,并匹配零个或一些名称空间。目标字段能以任意名称空间或无名称空间的形式拥有任何名称。它仅使用其类型、索引进行定位。或者在合适的地方,也可以使用其类型和索引进行定位。
* :NameId, *:NameId[..], (..)*:NameId, (..)*:NameId[..]
所有这些格式指定名称但不指定名称空间。目标字段使用名称进行定位。在合适的地方,也可以使用类型和索引进行定位。
SpaceId :*, SpaceId:*[..], (..)SpaceId:*, (..)SpaceId:*[..]
所有这些格式指定名称空间但不指定名称。目标字段使用名称空间进行定位。在合适的地方,也可以使用类型和索引进行定位。
SpaceId :NameId, SpaceId:NameId[..], (..)SpaceId:NameId, (..)SpaceId:NameId[..]
所有这些格式指定名称空间和名称。可以按名称空间和名称查找目标字段,适当的情况下,也可以按类型和索引查找。

在所有先前的例子中,包含在花括号({})中的表达式提供的名称或名称空间等同于作为标识提供的名称。

根据定义,notarget 名称空间的名称为空字符串。可通过求值为空字符串的表达式、空标识“”或对定义为空字符串的名称空间常量的引用来选择该空字符串。

目标字段引用

使用字段引用通常暗示要搜索已存在的字段。但是,如果必需的字段不存在(通常是 SET 语句的目标的字段引用和 SELECT 函数的 AS 子句中的那些字段引用),则创建它们。

在这些情况下,有各种代理无法分辨哪些是必需的名称或名称空间的情况,在这样的情况下,将应用以下一般原则:
  • 如果缺少名称子句或者没有指定名称,且缺少名称空间子句或者没有指定或暗指名称空间(即,没有可用的名称或名称空间),将应用以下条件之一:
    • 如果赋值算法从某些已存在的字段复制名称,新字段的名称和名称空间将设置为空字符串且不会自动设置它的名称标志。

      如果没有类型规范,元素的类型将不会是 NameNameValue,它实际上表明新字段是没有名称的。

      .
    • 否则,如果赋值算法选择从某些已存在的字段复制名称,新字段将从已存在的元素复制它的名称和名称空间,且自动设置它的 Name 标志。
  • 如果存在名称子句并指定名称,但缺少名称空间子句或者没有指定或暗指名称空间(即,名称是可用的,但名称空间不可用),则新字段具有:
    • Name 设置为给定值
    • Namespace 设置为空字符串
    • Name 标志(自动设置)
  • 如果缺少名称子句或者没有指定名称,但存在名称空间子句并指定或暗指了名称空间(即,名称空间是可用的,但名称不可用),则新字段具有:
    • Namespace 设置为给定值
    • Name 设置为空字符串
    • Name 标志(自动设置)
  • 如果存在名称子句并指定了名称,且存在名称空间子句并指定或暗指了名称空间,则新字段具有:
    • Name 设置为给定值
    • Namespace 设置为给定值
    • Name 标志(自动设置)
也存在代理除了创建字段引用所引用的字段,还创建其他字段的情况:
  • 树复制,使用将源树用作为模板的算法来创建新字段。如果算法将源字段的名称复制到新字段中,则也复制它的名称空间。
  • 匿名选择表达式:SELECT 子句不一定非要有 AS 子句;没有 AS 子句的 SELECT 子句将新创建的字段的名称设置为缺省值(请参阅 SELECT 函数)。

    这些缺省值可从字段名称、列名派生而来,或就是生成的顺序名称。如果它是字段名称(这实际上是树复制),名称空间名称按上面那样复制。

    否则,新创建的字段的名称空间将通过搜索路径派生而来,即,这些名称将作为它们是字段引用的 NameId 语法对待。

将字段设置为 NULL 的结果

向字段赋 null 值时应格外小心。例如,以下命令删除 Name 字段:
 SET OutputRoot.XML.Msg.Data.Name = NULL; -- this deletes the field
将 NULL 值赋给一个字段的正确方法是:
SET OutputRoot.XML.Msg.Data.Name VALUE = NULL;
-- this assigns a NULL value to a field without deleting it
注: 对于向后兼容性的用户

出于向下兼容的考虑,仍支持 LAST 关键字,但不推荐使用它。LAST 不能用作为索引表达式的一部分:[LAST] 是有效的,它等价于 [<],但 [LAST3] 是无效的。

LAST 关键字已被以下箭头语法替代,这种语法允许同时指定搜索和索引的方向:
      Field [ > ] -- The first field, equivalent to [ 1 ]
            Field [ > (a + b) * 2 ]
      Field [ < ] -- The last field, equivalent to [ LAST ]
      Field [ < 1 ] -- The last field, equivalent to [ LAST ]
      Field [ < 2 ] -- The last but one field
            Field [ < (a + b) / 3 ]
相关概念
ESQL 概述
声明 | 商标 | 下载 | 书库 | 支持 | 反馈
Copyright IBM Corporation 1999, 2006 最后一次更新时间:2006/08/14
ak04861_