Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  Stored Objects  /  Defining Stored Programs

27.1 存储程序的定义

每个存储程序都包含一个由 SQL 语句组成的主体。该语句可能是一个复合语句,由几个以分号 (;) 分隔的语句组成。例如,以下存储过程的主体由一个 BEGIN ... END 块组成,该块包含一个 SET 语句和一个 REPEAT 循环,该循环自身包含另一个 SET 语句:

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

如果您使用 mysql 客户端程序来定义包含分号字符的存储程序,会出现问题。默认情况下,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)