为 BREAK 定义一系列语句。
BEGIN SEQUENCE
<Statements>...
[BREAK [<uValue>]]
<Statements>...
[RECOVER [USING <idVar>]]
<Statements>...
END [SEQUENCE]
BREAK <uValue> | 如果指定了最近的 RECOVER 语句或最近的 END SEQUENCE 语句,则将执行分支到紧随其后的语句。 <uValue> 是返回到 RECOVER 语句的 USING 子句中指定的 <idVar> 中的值。 |
RECOVER USING <idVar> |
SEQUENCE 结构中的恢复点,在 BREAK 语句后,控制将在此点分支。 如果指定了该子句,<idVar> 将接收 BREAK 语句返回的值。 一般来说,这是一个错误对象。 <idVar> 必须是已声明的变量,并且不能是强类型变量。 |
END | SEQUENCE 控制结构的终点。 如果没有指定 RECOVER 语句,则在 BREAK 后将执行 END 语句之后的第一条语句。 |
BEGIN SEQUENCE...END 是一种控制结构,用于异常和运行时错误处理。 它限定了一个定义离散操作的语句块,包括调用的存储过程和函数。 除 BREAK 语句外,整个结构必须属于同一实体定义。
当在 BEGIN SEQUENCE 语句到相应的 RECOVER 语句之后的语句块中的任何地方遇到 "中断"(BREAK) 时,控制将分支到紧跟在 RECOVER 语句之后的程序语句。 如果没有指定 RECOVER 语句,控制将分支到 END 语句之后的语句,从而终止 SEQUENCE。 如果控制到达 RECOVER 语句时没有遇到 BREAK,则分支到相应的 END 语句之后的语句。
RECOVER 语句可选择接收 BREAK 语句传递的参数,该参数指定了返回值。 这通常是一个错误对象,由 ErrorBlock() 定义的当前错误处理块生成并返回。 如果返回了错误对象,则可以向其发送信息,以查询有关错误的信息。 有了这些信息,运行时错误就可以在操作的上下文中处理,而不是在当前的运行时错误处理程序中处理。
在 BEGIN SEQUENCE 和 RECOVER 语句之间不能使用 RETURN、LOOP 或 EXIT。
控制结构可以嵌套到任意深度。 唯一的要求是每个控制结构都必须正确嵌套。
该代码片段演示了一个 SEQUENCE 结构,其中的 BREAK 发生在当前过程中:
BEGIN SEQUENCE
<Statements>...
IF lBreakCond
BREAK
ENDIF
RECOVER
<Recovery Statements>...
END
<Recovery Statements>...
此示例演示了一个错误处理程序,它将向 RECOVER 语句的 USING 子句中指定的变量返回一个错误对象:
LOCAL oLocal, bLastHandler
// 保存当前错误处理程序,并设置新的错误处理程序
bLastHandler := ErrorBlock({|oErr| ;
MyHandler(oErr, TRUE)})
BEGIN SEQUENCE
.
. <可能失败的操作>...
.
RECOVER USING oLocal
// 向 oLocal 发送信息并处理错误
? "Error: "
IF oLocal:GenCode != 0
?? oLocal:Description
ENDIF
.
.
.
END
// 恢复先前的错误处理程序
ErrorBlock(bLastHandler)
FUNCTION MyHandler(oError, lLocalHandler)
// 返回错误对象的本地处理
IF lLocalHandler
BREAK oError
ENDIF
<处理错误的其他语句>...
此示例通过在 RECOVER 语句块内发出 LOOP,重新执行 SEQUENCE 语句块:
DO WHILE TRUE
BEGIN SEQUENCE
<可能失败的操作>...
RECOVER
IF PrintRecover()
// 重复 SEQUENCE 语句块
LOOP
ENDIF
END
EXIT // 逃离行动现场
ENDDO
_Break(), CanBreak(), Error Class, ErrorBlock(), RETURN