23.1 定义存储的程序

每个存储的程序都包含一个由 SQL 语句组成的主体。该语句可以是由多个用分号(;)字符分隔的语句组成的复合语句。例如,以下存储过程的主体由一个包含SET语句的开始...结束块和一个本身包含另一个SET语句的REPEAT循环组成:

CREATE PROCEDURE dorepeat(p1 INT)
BEGIN
  SET @x = 0;
  REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
END;

如果使用mysqlClient 端程序定义包含分号字符的存储程序,则会出现问题。默认情况下,mysql本身会将分号识别为语句定界符,因此您必须临时重新定义定界符,以使mysql将整个存储的程序定义传递给服务器。

要重新定义mysql分隔符,请使用delimiter命令。下面的示例说明如何针对刚刚显示的dorepeat()过程执行此操作。分隔符更改为//,以使整个定义可以作为单个语句传递到服务器,然后在调用该过程之前恢复为;。这使过程主体中使用的;分隔符可以传递到服务器,而不是由mysql本身解释。

mysql> delimiter //

mysql> CREATE PROCEDURE dorepeat(p1 INT)
    -> BEGIN
    ->   SET @x = 0;
    ->   REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> CALL dorepeat(1000);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x;
+------+
| @x   |
+------+
| 1001 |
+------+
1 row in set (0.00 sec)

您可以将定界符重新定义为//以外的字符串,并且定界符可以包含一个或多个字符。您应该避免使用反斜杠(\)字符,因为这是 MySQL 的转义字符。

下面是一个函数示例,该函数采用参数,使用 SQL 函数执行操作,然后返回结果。在这种情况下,不必使用delimiter,因为函数定义不包含内部;语句定界符:

mysql> CREATE FUNCTION hello (s CHAR(20))
mysql> RETURNS CHAR(50) DETERMINISTIC
    -> RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+
1 row in set (0.00 sec)