BEGIN ... END 语句

BEGIN ... END 语句使 BEGIN 和 END 关键字中定义的语句成为单语句。

它使包含的语句:
  • 可以成为函数或过程的主体
  • 能够让处理程序处理自己的异常
  • 能够用 LEAVE 语句中断自己的执行

语法

只有存在第一个 Label,第二个 Label 才能存在。而且如果两个 Label 都存在,它们必须相等。同一级别的两个或更多有标号语句可以有相同的标号,但这样会部分抵消使用第二个标号带来的好处。此处所说的好处是指标号可以明白、准确地与每个 END 及其 BEGIN 进行匹配。但是,上述语句中嵌套的有标号语句不能有相同的标号,因为这样会使 ITERATE 和 LEAVE 语句的行为不明确。

变量的作用域

打开 BEGIN 后会立即打开一个新的局部变量作用域,因此,当达到终止 END 时该语句中声明的所有变量都将超出作用域。如果局部变量与现有变量同名,声明之后任何对该名称的引用都会访问局部变量。例如:
DECLARE Variable1 CHAR 'Existing variable';

  -- A reference to Variable1 here returns 'Existing variable'

             BEGIN
    -- A reference to Variable1 here returns 'Existing variable'

    DECLARE Variable1 CHAR 'Local variable';  -- Perfectly legal even though 
the name is the same

    -- A reference to Variable1 here returns 'Local variable'
  END;

ATOMIC

如果指定了 ATOMIC,则同一时刻只能有一个消息流实例(即,一个线程)执行特定的 BEGIN ATOMIC... END 语句(用其模式和标号标识)中的语句。如果没有标号,则其行为与指定长度为零的标号相似。

当需要对共享变量进行大量更改时,BEGIN ATOMIC 构造十分有用;并且该构造对于防止其他实例查看数据的中间状态也非常重要。请参阅以下代码示例:
CREATE PROCEDURE WtiteSharedVariable1(IN NewValue CHARACTER)
SharedVariableMutex1 : BEGIN ATOMIC
  -- Set new value into shared variable
END;

CREATE FUNCTION ReadSharedVariable1() RETURNS CHARACTER
SharedVariableMutex1 : BEGIN ATOMIC
  DECLARE Value CHARACTER;
  -- Get value from shared variable
  RETURN Value;
  END;
最后一个示例假设过程 WriteSharedVariable1 和函数 ReadSharedVariable1 在同一模式中,并且被同一个流中的节点使用。但是,过程和函数是否包含在模块中或是否在相同节点中使用并不重要。代理会确保在任何时刻都只有一个线程在执行 Atomic 节中的语句。例如,这样可以确保两个并行写操作或并行写、读操作有序执行。注意:
  • 此序列只限于流。使用 BEGIN ATOMIC... END 语句且具有相同模式和标号的两个流可以同时执行。在这方面,流中的多个实例和流的多个副本是不相同的。
  • 此序列只限于模式和标号。在不同模式中指定或具有不同标号的 Atomic BEGIN ... END 语句不相互交互。
注: 如果您愿意,可以通过其他方式了解这一点。对于消息流、模式和标号的每种组合,代理有一种互斥,它阻止同时访问与此互斥关联的语句。

请勿嵌套 BEGIN ATOMIC... END 语句(无论直接还是间接),因为这会导致“死包含”。因此,请勿使用 Atomic 块中的 PROPAGATE 语句。

在从不部署一个以上实例(但如果让这种情况发生是不明智的)的流中没有必要使用 BEGIN ATOMIC 构造。读、写共享变量时也没有必要使用 BEGIN ATOMIC 构造。代理始终向共享变量安全地读、写新值。仅当应用程序需要查看中间结果时,才需要使用 ATOMIC。

请参阅以下示例:
DECLARE LastOrderDate SHARED DATE;
...
SET LastOrderDate = CURRENT_DATE;
...
SET OutputRoot.XMLNSC.Data.Orders.Order[1].Date = LastOrderDate;
在本例中,我们假设一个线程定期更新 LastOrderDate,另一个线程定期读取它。由于第二个 SET 语句始终读取有效值,因此不需要使用 ATOMIC。如果更新和读取之间的时间间隔非常短,是读取旧值还是新值并不确定,但始终不是新值就是旧值。结果总是有用的。
但现在请参阅以下示例:
DECLARE Count SHARED INT;
...
SET Count = Count + 1;
在本例中,我们假设多个线程定期执行 SET 语句。在这种情况下,您不需要使用 ATOMIC,因为两个线程可能几乎在同一时刻读取 Count,并获得相同的值。这两个线程都执行添加并回存相同的值。因此最终结果是 N+1,而不是 N+2。

代理不会自动提供比这更高级的锁定(例如,涵盖整个 SET 语句的锁定),因为这样的锁定不可靠,会导致“死包含”。

提示

您可以将 BEGIN ... END 语句视为循环构造,它总是只循环一次。BEGIN ... END 语句中嵌套的 ITERATE 或 LEAVE 语句的作用就是您希望的:将控制权转移到 END 后面的语句。在由于已获得明确的结果或发生了错误,需要放弃很长一系列计算的情况下,在 BEGIN ... END 语句中使用 ITERATE 或 LEAVE 非常有用。

相关概念
ESQL 概述
相关任务
正在开发 ESQL
相关参考
语法图:可用类型
ESQL 语句
声明 | 商标 | 下载 | 书库 | 支持 | 反馈
Copyright IBM Corporation 1999, 2006 最后一次更新时间:2006/08/14
ak04940_