• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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:
        (see following discussion)
    

    SIGNAL是“返回”错误的方法。SIGNAL将错误信息提供给处理程序,应用程序的外部或客户端。同样,它提供对错误特征(错误编号,SQLSTATE值,消息)的控制。如果不使用SIGNAL,则必须求助于变通办法,例如故意引用不存在的表以导致例程返回错误。

    执行该SIGNAL语句不需要特权。

    要从诊断区域检索信息,请使用该GET DIAGNOSTICS语句(请参见“ GET DIAGNOSTICS语句”)。有关诊断区域的信息,请参见“ MySQL诊断区域”。

    • 信号概述
    • 信号状态信息项
    • 信号对处理程序,游标和语句的影响

    信号概述

    condition_value一个SIGNAL声明中表示要返回错误值。它可以是一个SQLSTATE值(5个字符的字符串文字)或一个condition_name引用先前定义的命名条件的值DECLARE ... CONDITION(请参见“ DECLARE ... CONDITION语句”)。

    一个SQLSTATE值可以指示错误,警告或“未找到。”的值的前两个字符指示其错误类,如所讨论的信号状态信息项。一些信号值会导致语句终止。请参阅信号对处理程序,游标和语句的影响。

    语句的SQLSTATESIGNAL不应开头,'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 specialty CONDITION FOR SQLSTATE '45000';
      IF pval = 0 THEN
        SIGNAL SQLSTATE '01000';
      ELSEIF pval = 1 THEN
        SIGNAL SQLSTATE '45000'
          SET MESSAGE_TEXT = 'An error occurred';
      ELSEIF pval = 2 THEN
        SIGNAL specialty
          SET 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_bi BEFORE INSERT ON t
      FOR EACH ROW SIGNAL SQLSTATE '77777';
    
    CREATE EVENT e ON SCHEDULE EVERY 1 SECOND
      DO SIGNAL SQLSTATE '77777';
    

    SIGNAL根据以下规则执行:

    如果SIGNAL语句指示特定SQLSTATE值,则该值用于表示指定的条件。例:

    CREATE PROCEDURE p (divisor INT)
    BEGIN
      IF divisor = 0 THEN
        SIGNAL SQLSTATE '22012';
      END IF;
    END;
    

    如果该SIGNAL语句使用命名条件,则必须在适用于该SIGNAL语句的某个范围内声明该条件,并且必须使用SQLSTATE值(而不是MySQL错误号)进行定义。例:

    CREATE PROCEDURE p (divisor INT)
    BEGIN
      DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
      IF divisor = 0 THEN
        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_table CONDITION FOR 1051;
    SIGNAL no_such_table;
    

    如果在不同的作用域中多次声明了具有给定名称的条件,则使用具有最局部作用域的声明。请考虑以下过程:

    CREATE PROCEDURE p (divisor INT)
    BEGIN
      DECLARE my_error CONDITION FOR SQLSTATE '45000';
      IF divisor = 0 THEN
        BEGIN
          DECLARE my_error CONDITION 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。

    NULLSIGNAL语句中分配条件信息项是非法的。

    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'

      被视为普通异常。