除了默认的分隔符 ;
,通常在定义函数、存储过程和触发器时需要定义多条语句。你可以定义一个不同的分隔符,比如$$
,用于定义整个过程的结尾,在其中,每个语句都由;
结束。这样,在mysql
客户端运行代码时,客户端可以确定整个过程的结束并将其作为一个单元执行,而不是执行其中的各个语句。
请注意,关键字DELIMITER
只是命令行mysql
客户端(和一些其他客户端)的功能,而不是MySQL语言的常规特性。如果您尝试通过编程语言API将其传递到MySQL中,它将无法正常工作。像PHPMyAdmin这样的其他客户端有其他方法指定非默认分隔符。
DELIMITER $$
/* This is a complete statement, not part of the procedure, so use the custom delimiter $$ */
DROP PROCEDURE my_procedure$$
/* Now start the procedure code */
CREATE PROCEDURE my_procedure ()
BEGIN
/* Inside the procedure, individual statements terminate with ; */
CREATE TABLE tablea (
col1 INT,
col2 INT
);
INSERT INTO tablea
SELECT * FROM table1;
CREATE TABLE tableb (
col1 INT,
col2 INT
);
INSERT INTO tableb
SELECT * FROM table2;
/* whole procedure ends with the custom delimiter */
END$$
/* Finally, reset the delimiter to the default ; */
DELIMITER ;
如果尝试在不支持的客户端使用 DELIMITER
,它将会被发送到服务器,服务器将会报告语法错误。例如,使用 PHP 和 MySQLi:
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');
$result = $mysqli->query('DELIMITER $$');
echo $mysqli->error;
以下是错误信息:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER $$' at line 1
DELIMITER
关键字具有成为对用户施加不必要负担的所有方面,旨在规避MySQL客户端无法自行分段语句的愚蠢。似乎并不难认识到复合语句以END
或END IF
等终止。客户端可能能够自己做到这一点。 - davideDELIMITER语句用于改变标准分隔符,将分号(;)更改为其他字符。这里将分隔符从分号(;)更改为双斜杠(//)。
为什么要更改分隔符?
因为我们希望将存储过程、自定义函数等整体传递给服务器,而不是让MySQL工具逐条解释每个语句。
当您创建一个带有BEGIN...END
块的存储过程时,块内的语句由分号(;)
终止。但是,CREATE PROCEDURE
语句也需要一个终止符。因此,这就变得不明确了:例程体内的分号是用于终止CREATE PROCEDURE
,还是终止例程体内的语句之一。
解决歧义的方法是声明一个不同的字符串(不能在例程体内出现),MySQL客户端将其识别为CREATE PROCEDURE
语句的真正终止符。
你可以使用 DELIMITER 命令告诉 mysql 客户端将语句、函数、存储过程或触发器视为一个完整的语句。通常在 .sql 文件中,你会设置不同的 DELIMITER,比如 $$。DELIMITER 命令用于更改 MySQL 命令的标准分隔符(即 ;)。由于例程(函数、存储过程或触发器)中的语句以分号 (;) 结尾,因此我们使用 DELIMITER 将它们视为一个复合语句。如果在同一文件或命令行中使用不同的例程时未定义 DELIMITER,则会出现语法错误。
请注意,你可以使用各种非保留字符来制作自己的自定义分隔符。你应该避免使用反斜杠 (\) 字符,因为那是 MySQL 的转义字符。
DELIMITER 实际上并不是 MySQL 语言命令,而是客户端命令。
DELIMITER $$
/*This is treated as a single statement as it ends with $$ */
DROP PROCEDURE IF EXISTS `get_count_for_department`$$
/*This routine is a compound statement. It ends with $$ to let the mysql client know to execute it as a single statement.*/
CREATE DEFINER=`student`@`localhost` PROCEDURE `get_count_for_department`(IN the_department VARCHAR(64), OUT the_count INT)
BEGIN
SELECT COUNT(*) INTO the_count FROM employees where department=the_department;
END$$
/*DELIMITER is set to it's default*/
DELIMITER ;
;
作为分隔符,根据文档如下所示:
因此,在MySQL中,默认情况下可以使用以下SQL语句并包含分号如果您使用mysql客户端程序定义包含分号字符的存储程序,会出现问题。默认情况下,mysql本身将分号识别为语句分隔符,...
;
来运行: ↓
mysql> SELECT * FROM person;
+----+-------+
| id | name |
+----+-------+
| 1 | John |
| 2 | David |
+----+-------+
;
。 ↓
mysql> SELECT * FROM person ;
+----+-------+
| id | name |
+----+-------+
| 1 | John |
| 2 | David |
+----+-------+
--delimiter=
或--delimiter
将默认分隔符;
更改为hello
。*如果你退出登录,分隔符hello
会被改回默认分隔符;
。mysql -u john -p --delimiter=hello
或者:
mysql -u john -p --delimiter hello
delimiter
(DELIMITER
)和\d
将默认分隔符;
更改为hello
。*您必须在delimiter
(DELIMITER
)和hello
之间放置一个或多个空格,否则delimiter
命令不会运行,如果您使用\D
,则会出现错误ERROR: Unknown command '\D'.
。mysql> delimiter hello
或者:
mysql> DELIMITER hello
或者:
mysql> \d hello
或者:
mysql> \dhello
my.ini
中的[mysql]
下设置分隔符hello
。*我的回答解释了[mysql]
,我的回答解释了my.ini
在Windows上的位置。# "my.ini"
[mysql]
...
delimiter='hello'
my.ini
的位置设置为--defaults-file=
或--defaults-extra-file=
来使用登录设置分隔符hello
,如下所示。*--defaults-file=
或--defaults-extra-file=
必须是第一个选项,否则会出现错误。mysql --defaults-file='C:\ProgramData\MySQL\MySQL Server 8.0\my.ini' -u john -p
或者:
mysql --defaults-extra-file='C:\ProgramData\MySQL\MySQL Server 8.0\my.ini' -u john -p
hello
运行下面的SQL语句: ↓↓↓↓↓
mysql> SELECT * FROM personhello
+----+-------+
| id | name |
+----+-------+
| 1 | John |
| 2 | David |
+----+-------+
hello
。 ↓↓↓↓↓
mysql> SELECT * FROM person hello
+----+-------+
| id | name |
+----+-------+
| 1 | John |
| 2 | David |
+----+-------+
hello
更改为;
。*请务必在delimiter
和;
之间放置一个或多个空格,否则delimiter
命令将无法运行。delimiter ;
;
更改为$$
之类的内容,然后在创建事件之后,您需要将分隔符$$
改回;
,如下所示。*我的答案解释了MySQL中的事件,创建事件时必须选择一个数据库,否则会出现错误。mysql> USE apple;
mysql> delimiter $$
-> CREATE EVENT my_event
-> ON SCHEDULE EVERY 1 DAY
-> STARTS '2023-11-08 00:00:00'
-> DO
-> BEGIN
-> SELECT * FROM person;
-> END$$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
;
更改为$$
之类的内容,那么您将会收到如下所示的错误信息:mysql> USE apple;
mysql> CREATE EVENT my_event
-> ON SCHEDULE EVERY 1 DAY
-> STARTS '2023-11-08 00:00:00'
-> DO
-> BEGIN
-> SELECT * FROM person;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 6