0

特别是我在这里阅读有关退出处理程序的信息:

handler_action 值指示处理程序在执行处理程序语句后采取的操作: CONTINUE:继续执行当前程序。

这句话中“程序”的范围是什么?我可以问更具体的问题,这应该回答:

  • 它必须在存储过程或存储函数中吗?
  • 它是否仅适用于我正在执行的语句集,或者通过executeJDBC 等驱动程序中的一个语句,或者在 MySQL Workbench 等程序中作为块运行?
  • 驱动程序是否有责任将一个程序与另一个程序分开?

我这里唯一的“线索”是declare的文档:

DECLARE 仅允许在 BEGIN ... END 复合语句中使用,并且必须位于其开头,在任何其他语句之前。

这至少意味着声明的处理程序的范围很紧,所以这不会污染整个连接。

我之所以这么普遍地提出这个问题是因为我试图从 SQL 101 的选择、更新、插入和删除中毕业,从而编写更复杂的、性能感知的任务。但是我发现的一个绊脚石是MySQL程序“是”的基础知识,除了一组语句我很难理解。

4

1 回答 1

0

这里使用的程序与“存储程序”的含义相同。

存储的程序包括以下对象:

存储例程,即存储过程[存储]函数。使用该CALL语句调用存储过程。过程没有返回值,但可以修改其参数以供调用者稍后检查。它还可以生成要返回给客户端程序的结果集。存储函数的使用很像内置函数。您在表达式中调用它,它会在表达式评估期间返回一个值。

触发器。触发器是与表相关联的命名数据库对象,当表发生特定事件(例如插入或更新)时,触发器将被激活。

事件。事件是服务器按计划运行的任务。

http://dev.mysql.com/doc/refman/5.6/en/stored-programs-views.html

这不包括您可能作为查询执行的任何其他操作,包括服务器端准备好的语句和多语句执行

这有点不准确,但总的来说它认为存储过程具有最完整的功能,通常对您可以做的事情的限制较少,但是这 4 种类型的存储程序有很多共性。

当存储的程序可以不使用任何分号来表示时,例如...

CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW DELETE FROM t2 WHERE t2.id = NEW.id;

...那么存储的程序不需要BEGIN/END块。几乎任何更复杂的东西本质上都是 a并且必须用/compound statement包围,这是唯一可以使用 a 的地方。BEGINENDHANDLER

这些块可以嵌套在单个存储程序的主体中,并且除了最简单的情况外,每个存储程序都至少有一个——最外面的一个。

AHANDLER的范围是包含处理程序声明的最外层块,以及该块中没有可以捕获条件的处理程序的任何块。在任何情况下,处理程序都不能捕获在声明它的块开始之前或结束之后发生的条件。

AHANDLER的范围包括处理程序在范围内时程序所做的任何事情,这可能包括在相同条件下调用其他没有自己的处理程序的存储过程或函数。

CONTINUE由于指定条件发生而触发处理程序时,将执行由处理程序声明(见下文)指定的语句,然后程序继续优雅地执行到导致异常的语句之后的下一条语句,无论发生在何处。 当然,这里的限制是它只能在处理程序范围内的某个地方。严格使用其他不必要的BEGIN/END块来将处理程序保持在单个语句或少量语句的范围内的情况并不少见,而处理程序不适合逗留和捕获不应该的条件抓住。

与处理程序相反CONTINUE,当EXIT处理程序触发时,将执行处理程序指定的语句(见下文),然后END在声明处理程序的块的底部之后继续执行程序。如果这是END一个过程的结尾,则过程会优雅地终止,因为错误已由处理程序处理。如果该过程被另一个过程调用,则控制权返回到调用过程。

无论哪种方式,处理程序都会在适当的点继续执行之前执行“一条语句”。“声明”可以很简单,

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @something_happened = 1;

或复合(带BEGIN/ END)。

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SET @foo = 1; DELETE FROM t1; ROLLBACK; END;

在前一种情况下,简单语句有时用于设置在别处编码的变量,稍后可用于检测条件发生并在适当的时间做出相应的反应,而不是在处理程序触发时立即做出反应。

于 2013-09-18T00:19:21.060 回答