消息选择器语法

IBM® MQ 消息选择器是具有基于 SQL92 条件表达式语法子集的语法的字符串。

消息选择器的求值顺序为同一优先顺序级别内从左到右。 可使用括号来更改这一顺序。 预定义选择器字面值和运算符名称在此处以大写写入;但是,这些文本和运算符不区分大小写。

如果通过 API 提供选择器,那么 IBM MQ 会在显示消息选择器时验证其语法正确性。 如果选择字符串的语法不正确或属性名无效,并且扩展消息选择提供程序不可用,那么会将 MQRC_SELECTION_NOT_AVAILABLE 返回到应用程序。 如果恢复预订时选择字符串的语法不正确或属性名称无效,将向应用程序返回 MQRC_SELECTOR_SYNTAX_ERROR。 如果设置属性时禁用了属性名称验证(设置 MQCMHO_NONE,而不是 MQCMHO_VALIDATE),而应用程序随后放入了具有无效属性名称的消息,那么不会选择此消息。

如果 IBM MQ 确定以管理方式定义的预订选择器正在使用扩展消息语法 (如具有值 EXTENDEDDISPLAY SUB 参数 SELTYPE 所指示) ,那么在提供选择器时不会返回任何错误。 在这种情况下,选择字符串的语法检查将延迟到发布时间 (请参阅 MQRC_SELECTION_NOT_AVAILABLE)。

选择器可以包含:
  • 字面值:
    • 字符串字面值以单引号括起。 两个连续的单引号表示一个单引号。 例如,'literal' 和 'literal''s'。 与 Java 字符串字面值一样,这些字面值使用 Unicode 字符编码。 不能使用双引号括起字符串字面值。 单引号之间可以使用任何字节序列。
    • 字节字符串是一对或多对十六进制字符,这些字符以双引号括起并带有前缀 0x。 示例为 0x2F1C0XD43A。 字节字符串的长度必须至少一个字节。 如果选择器字节字符串与 MQTYPE_BYTE_STRING 类型的消息属性匹配,那么不需要对前导零或后导零采取特殊操作。 这些字节将视为另外的字符。 同时不考虑字节顺序。 选择器和属性字节字符串的长度必须相等,且字节的顺序必须相同。
      下面是匹配的字节字符串选择示例(假设 myBytes = 0AFC23):
      • myBytes = 0x0AFC23 = TRUE
      以下字符串选择不匹配:
      • myBytes = 0xAFC23 = MQRC_SELECTOR_SYNTAX_ERROR(因为字节数量不是 2 的倍数)
      • myBytes = 0x0AFC2300 = FALSE(因为相较之下,后导零非常重要)
      • myBytes = 0x000AFC23 = FALSE(因为相较之下,前导零非常重要)
      • myBytes = 0x23FC0A = FALSE(因为不考虑字节顺序)
    • 十六进制数字以 0 开头,后跟大写或小写 x。 文字的其余部分包含一个或多个有效十六进制字符。 例如,0xA0xAF0X2020
    • 后跟一个或多个 0-7 范围内数字的前导零将始终认为是八进制数字的开头。 不能像以下示例这样表示以零为前缀的小数,例如,09 将返回语法错误,因为 9 不是有效的八进制数字。 八进制数字的示例有 01770713
    • 准确的数字字面值为不带小数点的数字值,例如 57-957+62。 准确的数字字面值结尾可以有大写或小写的 L;这不会影响数字的存储方式和理解方式。 IBM MQ 支持范围在 -9,223,372,036,854,775,8089,223,372,036,854,775,807之间的精确数字。
    • 近似数字字面值是科学记数法格式的数字值,如 7E3-57.9E2,或带有小数点的数字值,如 7.-95.7+6.2IBM MQ 支持 -1.797693134862315E+3081.797693134862315E+308范围内的数字。

      有效数字应跟在可选符号字符(+-)后。 有效数字应为整数或小数。 有效数字的小数部分不需要前导数字。

      大写或小写的 E 表示可选指数的开头。 指数有十进制基数,指数的数字部分可以加上可选符号字符前缀。

      近似数字字面值可以以 FD 字符(不区分大小写)结尾。 此语法的存在用于支持跨语言标记单精度或双精度数字的方式。 这些字符为可选字符,不会影响近似数字字面值的存储和处理方式。 始终会使用双精度存储和处理这些数字。

    • 布尔文字 TRUEFALSE
    注: 在选择字符串中不支持非有限 IEEE-754 表示,例如 NaN+Infinity-Infinity 。 因此不能使用这些值作为表达式中的操作数。 对于数学运算而言,负零将视为与正零相同。
  • 标识符:

    标识符是长度可变的字符顺序,必须以有效的标识符起始符开头,后跟零个或更多有效标识符组成字符。 标识符名称的规则与报文属性名称的规则相同,更多信息请参阅 Property namesProperty name restrictions

    注: 仅当扩展消息选择提供程序可用时,才能对消息有效内容执行选择。

    标识为头字段引用或属性引用。 尽管会尽量执行数字提升,但消息选择器内属性值的类型必须与用于设置属性的类型对应。 如果出现类型不匹配,表达式的结果将为 FALSE。 如果引用了消息中不存在的属性,其值将为 NULL

    当属性用在消息选择器表达式中时,适用于属性获取方法的类型转换不适用。 例如,如果您将属性设置为字符串值,然后使用选择器按照数字值查询此属性,表达式将返回 FALSE

    映射到属性名称或 MQMD 字段名称的 JMS 字段和属性名称也是选择字符串中的有效标识。 IBM MQ 将识别的 JMS 字段和属性名称映射到消息属性值。 有关详细信息,请参阅 JMS 中的消息选择器。 例如,选择字符串 JMSPriority >= 在当前消息的 jms 文件夹中的 Pri 属性上选择。

  • 溢出/下溢:
    对于十进制和近似数字,未定义以下条件:
    • 指定不在定义范围内的数字
    • 指定将导致溢出或下溢的算术表达式
    不会对以上情况执行检查。
  • 空格:
    定义为空格、换页符、换行符、回车符、横向制表符或纵向制表符。 以下 Unicode 字符将识别为空格:
    • \u0009 to \u000D
    • \u0020
    • \u001C
    • \u001D
    • \u001E
    • \u001F
    • \u1680
    • \u180E
    • \u2000\u200A
    • \u2028
    • \u2029
    • \u202F
    • \u205F
    • \u3000
  • 表达式:
    • 选择器是条件表达式。 求值结果为 true 的选择器匹配;结果为 false 或未知值的选择器不匹配。
    • 算术表达式由自身、算术运算、标识符(标识符值被视为数字字面值)和数字字面值组成。
    • 条件表达式由其自身、比较运算符以及逻辑运算符组成。
  • 支持用于设置表达式求值顺序的标准括号 ()。
  • 按照优先顺序排列的逻辑运算符:NOTANDOR
  • 比较运算符:=>>=<<=<>(不等于)。
    • 两个字节字符串只有在长度相同且字节顺序相同的情况下才相等。
    • 只能比较相同类型的值。 一个例外是,将精确数字值与近似数字值进行比较是有效的 (所需类型转换由 Java 数字提升的规则定义)。 如果尝试比较不同的类型,那么选择器将始终为 false。
    • 字符串和布尔值比较限制为 =<>。 两个字符串只有在包含相同顺序的字符时才相等。
  • 按照优先顺序排列的算术运算符:
    • +- 一元。
    • * 乘法和 / 除法。
    • + 加法和 - 减法。
    • 不支持对 NULL 值使用算术运算。 如果尝试使用,那么整个选择器均始终为 false。
    • 算术运算必须使用 Java 数字提升。
  • arithmetic-expr1 [ NOT ] BETWEEN arithmetic-expr2 and arithmetic-expr3 比较运算符:
    • Age BETWEEN 15 and 19 等于 age>= 15 AND age <= 19
    • Age NOT BETWEEN 15 and 19 等于 age < 15 OR age > 19
    • 如果任何 BETWEEN 运算的表达式为 NULL,那么运算值为 false。 如果任何 NOT BETWEEN 运算的表达式为 NULL,那么运算值为 true。
  • 标识 [NOT] IN (string-literal1, string-literal2,...) 比较运算符,其中标识具有字符串或 NULL 值。
    • Country IN ('UK', 'US', 'France') 对于 'UK' 为 true,对于 'Peru' 为 false。 它相当于表达式 (Country = 'UK') OR (Country = 'US') OR (Country = 'France')
    • Country NOT IN ('UK', 'US', 'France') 对于 'UK' 为 false,对于 'Peru' 为 true。 它相当于表达式 NOT ((Country = 'UK') OR (Country = 'US') OR (Country = 'France'))
    • 如果 INNOT IN 运算的标识符为 NULL,那么运算值未知。
  • identifier [NOT] LIKE pattern-value [ESCAPE escape-character ] 比较运算符,其中 identifier 具有字符串值。 pattern-value 是字符串字面值,其中 _ 代表任意单个字符,而 % 代表任何字符序列(包括空序列)。 所有其他字符均代表其自身。 可选的 escape-character 是单个字符串文字,用于对 pattern-value_% 的特殊含义进行转义。 LIKE 运算符只能用于比较两个字符串值。
    • phone LIKE '12%3' 对于 123 和 12993 为 true,对于 1234 为 false。
    • word LIKE 'l_se' 对于 lose 为 true,对于 loose 为 false。
    • underscored LIKE '\_%' ESCAPE '\' 对于 _foo 为 true,对于 bar 为 false。
    • phone NOT LIKE '12%3' 对于 12312993 为 false,对于 1234 为 true。
    • 如果 LIKENOT LIKE 运算的标识符为 NULL,那么此运算的值为 unknown。
    注: 必须使用 LIKE 运算符来比较两个字符串值。 Root.MQMD.CorrelId 的值为 24 字节的字节数组,而不是字符串。 解析器接受选择器字符串 Root.MQMD.CorrelId LIKE 'ABC%' 作为有效语法,但会求值为 false。 因此在比较字节数组和字符串时,不会使用 LIKE
  • identifier IS NULL 比较运算符测试是否存在 NULL 头字段值或是否缺失属性值。
  • identifier IS NOT NULL 比较运算符测试是否存在非空头字段值或属性值。
  • null 值
    总而言之,包含 NULL 值的选择器表达式的求值由 SQL 92 NULL 语义定义:
    • SQL 将 NULL 值视为 unknown。
    • 带有 unknown 值的比较或算术始终会产生 unknown 值。
    • IS NULLIS NOT NULL 运算符可将 unknown 值转换为 TRUEFALSE 值。
    布尔运算符使用三值逻辑(T=TRUEF=FALSEU=UNKNOWN
    表 1. 逻辑为 A AND B 时布尔运算符结果的值
    运算符 A 运算符 B 结果 (A AND B)
    T F F
    T U U
    T T T
    F T F
    F U F
    F F F
    U T U
    U U U
    U F F
    表 2. 逻辑为 A OR B 时布尔运算符结果的值
    运算符 A 运算符 B 结果 ( A OR B)
    T F T
    T U T
    T T T
    F T T
    F U U
    F F F
    U T T
    U U U
    U F U
    表 3. 逻辑为 NOT A 时布尔运算符结果的值
    运算符 A 结果 ( NOT A)
    T F
    F T
    U U
以下消息选择器选择消息类型为汽车,颜色为蓝色且重量大于 2500 磅的消息:
"JMSType = 'car' AND color = 'blue' AND weight > 2500"

尽管 SQL 支持固定的小数比较和算术,但消息选择器并不支持。 这是因为精确数字字面值限制为不带小数点的数字。 还因为某些带有小数点的数字作为近似数字值的替代表示。

不支持 SQL 注释。