## 25.1 定义存储程序

每个存储的程序都包含一个由 SQL 语句组成的主体。该语句可能是由分号分隔的若干语句组成的复合语句 (`;`） 人物。例如，以下存储过程的主体由[`开始...结束`](begin-end.html)包含一个块[`放`](set-variable.html)声明和一个[`重复`](repeat.html)本身包含另一个的循环[`放`](set-variable.html)陈述：

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

如果您使用[**mysql**](mysql.html)客户端程序定义一个包含分号字符的存储程序，问题就出现了。默认，[**mysql**](mysql.html)本身将分号识别为语句分隔符，因此必须临时重新定义分隔符以导致[**mysql**](mysql.html)将整个存储的程序定义传递给服务器。

重新定义[**mysql**](mysql.html)分隔符，使用`分隔符`命令。以下示例显示了如何为`重复（）`刚刚显示的过程。分隔符更改为`//`使整个定义能够作为单个语句传递到服务器，然后恢复到`;`在调用程序之前。这使`;`过程主体中使用的分隔符被传递到服务器而不是被解释[**mysql**](mysql.html)本身。

```
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 函数执行操作并返回结果。在这种情况下，没有必要使用`分隔符`因为函数定义不包含内部`;`语句分隔符：

```
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)
```
