SIGNAL语句
SIGNAL condition_value [SET signal_information_item [, signal_information_item] ...] condition_value: {SQLSTATE [VALUE ] sqlstate_value | condition_name } signal_information_item: condition_information_item_name = simple_value_specification condition_information_item_name: {CLASS_ORIGIN |SUBCLASS_ORIGIN |MESSAGE_TEXT |MYSQL_ERRNO |CONSTRAINT_CATALOG |CONSTRAINT_SCHEMA |CONSTRAINT_NAME |CATALOG_NAME |SCHEMA_NAME |TABLE_NAME |COLUMN_NAME |CURSOR_NAME } condition_name, simple_value_specification: (seefollowing discussion)
SIGNAL是“返回”错误的方法。SIGNAL将错误信息提供给处理程序,应用程序的外部或客户端。同样,它提供对错误特征(错误编号,SQLSTATE值,消息)的控制。如果不使用SIGNAL,则必须求助于变通办法,例如故意引用不存在的表以导致例程返回错误。
执行该SIGNAL语句不需要特权。
要从诊断区域检索信息,请使用该GET DIAGNOSTICS语句(请参见“ GET DIAGNOSTICS语句”)。有关诊断区域的信息,请参见“ MySQL诊断区域”。
- 信号概述
- 信号状态信息项
- 信号对处理程序,游标和语句的影响
信号概述
在condition_value一个SIGNAL声明中表示要返回错误值。它可以是一个SQLSTATE值(5个字符的字符串文字)或一个condition_name引用先前定义的命名条件的值DECLARE ... CONDITION(请参见“ DECLARE ... CONDITION语句”)。
一个SQLSTATE值可以指示错误,警告或“未找到。”的值的前两个字符指示其错误类,如所讨论的信号状态信息项。一些信号值会导致语句终止。请参阅信号对处理程序,游标和语句的影响。
语句的SQLSTATE值SIGNAL不应开头,'00'因为这样的值表示成功,并且对于发信号错误无效。无论SQLSTATE是直接在SIGNAL语句中还是在语句中引用的命名条件中指定值,都是如此。如果该值无效,Bad SQLSTATE则会发生错误。
为了用信号的通用SQLSTATE值,使用'45000',这意味着“未处理用户定义的异常。”
该SIGNAL语句可选地包含一个SET子句,该子句在condition_information_item_name=simple_value_specification分配列表中包含多个信号项,并用逗号分隔。
每个子句condition_information_item_name只能在SET子句中指定一次。否则,将Duplicate condition information item发生错误。
simple_value_specification可以使用存储过程或函数参数,用声明的存储程序局部变量DECLARE,用户定义的变量,系统变量或文字来指定有效的指示符。字符文字可能包括_charset介绍人。
有关允许condition_information_item_name值的信息,请参见信号条件信息项。
以下过程根据pval输入参数的值发出错误或警告信号:
CREATE PROCEDURE p (pval INT)BEGIN DECLARE specialtyCONDITION FOR SQLSTATE '45000';IF pval = 0THEN SIGNAL SQLSTATE '01000';ELSEIF pval = 1THEN SIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'An error occurred';ELSEIF pval = 2THEN SIGNAL specialtySET MESSAGE_TEXT = 'An error occurred';ELSE SIGNAL SQLSTATE '01000'SET MESSAGE_TEXT = 'A warning occurred',MYSQL_ERRNO = 1000;SIGNAL SQLSTATE '45000'SET MESSAGE_TEXT = 'An error occurred',MYSQL_ERRNO = 1001;END IF ;END ;
如果pval为0,则p()发出警告,因为SQLSTATE以开头的值是'01'警告类中的信号。该警告不会终止该过程,可以SHOW WARNINGS在过程返回后看到。
如果pval为1,则p()指示错误并设置MESSAGE_TEXT条件信息项。错误将终止该过程,并返回包含错误信息的文本。
如果pval为2,则发出相同的错误信号,尽管SQLSTATE在这种情况下使用命名条件指定了该值。
如果pval还有其他内容,则p()首先发出警告并设置消息文本和错误编号条件信息项。该警告不会终止该过程,因此执行继续,p()然后发出错误信号。该错误确实终止了该过程。警告设置的消息文本和错误编号将替换为错误设置的值,并随错误信息一起返回。
SIGNAL通常在存储程序中使用,但它是MySQL扩展,可以在处理程序上下文外部使用。例如,如果调用mysql客户端程序,则可以在提示符下输入以下任何语句:
SIGNAL SQLSTATE '77777';CREATE TRIGGER t_biBEFORE INSERT ON tFOR EACH ROW SIGNAL SQLSTATE '77777';CREATE EVENT eON SCHEDULE EVERY 1SECOND DO SIGNAL SQLSTATE '77777';
SIGNAL根据以下规则执行:
如果SIGNAL语句指示特定SQLSTATE值,则该值用于表示指定的条件。例:
CREATE PROCEDURE p (divisor INT)BEGIN IF divisor = 0THEN SIGNAL SQLSTATE '22012';END IF ;END ;
如果该SIGNAL语句使用命名条件,则必须在适用于该SIGNAL语句的某个范围内声明该条件,并且必须使用SQLSTATE值(而不是MySQL错误号)进行定义。例:
CREATE PROCEDURE p (divisor INT)BEGIN DECLARE divide_by_zeroCONDITION FOR SQLSTATE '22012';IF divisor = 0THEN SIGNAL divide_by_zero;END IF ;END ;
如果命名条件在SIGNAL语句范围内不存在,Undefined CONDITION则会发生错误。
如果SIGNAL引用使用MySQL错误号而不是SQLSTATE值定义的命名条件,SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE则会发生错误。以下语句导致该错误,因为命名条件与MySQL错误号相关联:
DECLARE no_such_tableCONDITION FOR 1051;SIGNAL no_such_table;
如果在不同的作用域中多次声明了具有给定名称的条件,则使用具有最局部作用域的声明。请考虑以下过程:
CREATE PROCEDURE p (divisor INT)BEGIN DECLARE my_errorCONDITION FOR SQLSTATE '45000';IF divisor = 0THEN BEGIN DECLARE my_errorCONDITION FOR SQLSTATE '22012';SIGNAL my_error;END ;END IF ;SIGNAL my_error;END ;
如果divisor为0,则SIGNAL执行第一条语句。最里面的my_error条件声明适用,raising SQLSTATE'22012'。
如果divisor不为0,则SIGNAL执行第二条语句。最外面的my_error条件声明适用,raising SQLSTATE'45000'。
有关在条件发生时服务器如何选择处理程序的信息,请参见“处理程序的作用域规则”。
可以在异常处理程序中引发信号:
CREATE PROCEDURE p ()BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN SIGNAL SQLSTATE VALUE '99999'SET MESSAGE_TEXT = 'An error occurred';END ;DROP TABLE no_such_table;END ;
CALL p()到达DROP TABLE声明。没有名为的表no_such_table,因此错误处理程序已激活。错误处理程序销毁原始错误(“没有这样的表”),并使用SQLSTATE'99999'和消息进行新的错误处理An error occurred。
信号状态信息项
下表列出了可以在SIGNAL(或RESIGNAL)语句中设置的诊断区域条件信息项的名称。除之外MYSQL_ERRNO,所有项目均为标准SQL ,这是MySQL扩展。有关这些项目的更多信息,请参见“ MySQL诊断区域”。
Item Name Definition --------- ---------- CLASS_ORIGIN VARCHAR(64) SUBCLASS_ORIGIN VARCHAR(64) CONSTRAINT_CATALOG VARCHAR(64) CONSTRAINT_SCHEMA VARCHAR(64) CONSTRAINT_NAME VARCHAR(64) CATALOG_NAME VARCHAR(64) SCHEMA_NAME VARCHAR(64) TABLE_NAME VARCHAR(64) COLUMN_NAME VARCHAR(64) CURSOR_NAME VARCHAR(64) MESSAGE_TEXT VARCHAR(128) MYSQL_ERRNO SMALLINT UNSIGNED
字符项的字符集为UTF-8。
NULL在SIGNAL语句中分配条件信息项是非法的。
甲SIGNAL语句总是指定一个SQLSTATE值,或者直接地或间接地通过参照具有一个定义的命名条件SQLSTATE值。值的前两个字符SQLSTATE是其类,并且该类确定条件信息项的默认值:
- 类别= - '00'(成功)- 非法。 - SQLSTATE以开头的值- '00'表示成功,不适用于- SIGNAL。
- 类别= - '01'(警告)- MESSAGE_TEXT = 'Unhandled user-defined warning condition';- MYSQL_ERRNO = ER_SIGNAL_WARN
- 类= - '02'(未找到)- MESSAGE_TEXT = 'Unhandled user-defined not found condition';- MYSQL_ERRNO = ER_SIGNAL_NOT_FOUND
- 类别> - '02'(例外)- MESSAGE_TEXT = 'Unhandled user-defined exception condition';- MYSQL_ERRNO = ER_SIGNAL_EXCEPTION
对于合法类,其他条件信息项设置如下:
CLASS_ORIGIN =SUBCLASS_ORIGIN = '';CONSTRAINT_CATALOG =CONSTRAINT_SCHEMA =CONSTRAINT_NAME = '';CATALOG_NAME =SCHEMA_NAME =TABLE_NAME =COLUMN_NAME = '';CURSOR_NAME = '';
SIGNAL执行后可访问的错误值是语句以及和项目SQLSTATE引发的值。这些值可从C API获得:SIGNALMESSAGE_TEXTMYSQL_ERRNO
- mysql_sqlstate()返回- SQLSTATE值。
- mysql_errno()返回- MYSQL_ERRNO值。
- mysql_error()返回- MESSAGE_TEXT值。
在SQL级别,SHOW WARNINGSand 的输出SHOW ERRORS表示and 列中的MYSQL_ERRNO and MESSAGE_TEXT值。CodeMessage
要从诊断区域检索信息,请使用该GET DIAGNOSTICS语句(请参见“ GET DIAGNOSTICS语句”)。有关诊断区域的信息,请参见“ MySQL诊断区域”。
信号对处理程序,游标和语句的影响
根据信号类别,信号对语句执行的影响不同。该类确定错误的严重程度。MySQL会忽略sql_mode系统变量的值。特别是,严格的SQL模式无关紧要。MySQL还忽略了IGNORE:的目的SIGNAL是显式引发用户生成的错误,因此永远不会忽略信号。
在以下描述中,“未处理”表示SQLSTATE尚未使用定义信号值的处理程序DECLARE ... HANDLER。
- 类别= - '00'(成功)- 非法。 - SQLSTATE以开头的值- '00'表示成功,不适用于- SIGNAL。
- 类别= - '01'(警告)- warning_count系统变量的值上升。- SHOW WARNINGS显示信号。- SQLWARNING处理程序捕获信号。- 无法从存储的函数返回警告,因为 - RETURN引起函数返回的语句清除了诊断区域。因此,该语句清除了那里可能存在的所有警告(并将其重置- warning_count为0)。
- 类= - '02'(未找到)- NOT FOUND处理程序捕获信号。对光标没有影响。如果未在存储的函数中处理信号,则语句结束。
- 类别> - '02'(例外)- SQLEXCEPTION处理程序捕获信号。如果未在存储的函数中处理信号,则语句结束。
- 类= - '40'- 被视为普通异常。 
