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 $$
/*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> 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
5条答案
按热度按时间iq3niunx1#
在定义函数、存储过程和触发器时,通常会使用除默认值
;
以外的分隔符,其中必须定义多个语句。您可以定义一个不同的分隔符,如$$
,用于定义整个过程的结束,但在该分隔符中,各个语句都以;
结束。这样,当代码在mysql
客户端中运行时,客户端可以知道整个过程在哪里结束,并将其作为一个单元执行,而不是执行内部的各个语句。请注意,
DELIMITER
关键字仅是mysql
客户端(和其他一些客户端)命令行的一个功能,而不是常规的MySQL语言功能。如果您试图通过编程语言API将其传递到MySQL,它将不起作用。其他一些客户端(如PHPMyAdmin)有其他方法来指定非默认的MySQL。示例:
字符串
如果在不支持
DELIMITER
的客户端上尝试使用DELIMITER
,则会将DELIMITER
发送到服务器,服务器会报告语法错误。例如,使用PHP和MySQLi:型
错误:
您的SQL语法中有一个错误;请检查与您的MySQL服务器版本对应的手册,以获得在第1行'DELIMITER $$'附近使用的正确语法
xxhby3vn2#
DELIMITER语句将标准的字符串从字符串(;)改为另一个字符串。字符串从字符串(;)改为双斜杠//。
为什么我们要改变这一点?
因为我们希望将存储过程、自定义函数等作为一个整体传递给服务器,而不是让mysql工具一次解释每个语句。
eblbsuwk3#
当你创建一个有
BEGIN...END
块的存储例程时,块内的语句由(;)
上的终止符终止。但是CREATE PROCEDURE
语句也需要一个终止符。所以例程体内的终止符是终止CREATE PROCEDURE
,还是终止过程体内的一个语句变得不明确。解决这种不明确性的方法是声明一个独特的字符串(不能出现在过程的主体中),MySQL客户端将其识别为
CREATE PROCEDURE
语句的真正终止符。j2datikz4#
你定义一个DELIMITER来告诉mysql客户端将语句、函数、存储过程或触发器作为一个完整的语句来处理。通常在.sql文件中你设置一个不同的DELIMITER,比如$$。DELIMITER命令用于更改MySQL命令的标准格式(即;)。作为例程中的语句,(函数、存储过程或触发器)以分号(;),把它们当作一个复合语句我们使用DELIMITER.如果没有定义时,在同一文件或命令行中使用不同的例程,它会给给予语法错误.
请注意,您可以使用各种非保留字符来创建自己的自定义字符串。您应该避免使用反斜杠(\)字符,因为这是MySQL的转义字符。
DELIMITER实际上不是MySQL语言命令,而是客户端命令。
示例
字符串
gcxthw6b5#
在MySQL中,字符串是运行SQL语句的一个或多个字符,根据the doc,
;
默认用作字符串,如下所示:如果你使用mysql客户端程序来定义一个存储程序,其中包含了一个字符串,那么就会出现一个问题。默认情况下,mysql本身会将这个字符串识别为一个语句,...
因此,您可以在MySQL中默认使用
;
运行以下SQL语句:字符串
而且,即使它们之间有一些空格,您仍然可以使用
;
运行下面的SQL语句:型
并且,您可以在登录时使用
--delimiter=
或--delimiter
将默认的;
更改为hello
。* 如果注销,则hello
将更改回默认的;
:型
或者:
型
或者,您可以使用
delimiter
(DELIMITER
)和\d
将默认的;
更改为hello
。* 您必须在delimiter
(DELIMITER
)和hello
之间放置一个或多个空格,否则delimiter
命令不会运行,如果您使用\D
,则会收到错误ERROR: Unknown command '\D'.
:型
或者:
型
或者:
型
或者:
型
或者在Windows上,您可以在
my.ini
中的[mysql]
下设置hello
,如下所示。* 我的答案解释了[mysql]
,我的答案解释了my.ini
在Windows上的位置:型
然后,您可以通过将
my.ini
的位置设置为--defaults-file=
或--defaults-extra-file=
来设置带登录的hello
,如下所示。*--defaults-file=
或--defaults-extra-file=
必须是第一个选项,否则会出现错误:型
或者:
型
然后,您可以使用
hello
运行下面的SQL语句:型
而且,即使它们之间有一些空格,您仍然可以使用
hello
运行下面的SQL语句:型
如果你想再次使用
;
作为一个字符串,你可以将hello
更改为;
,如下所示。* 你必须在delimiter
和;
之间放置一个或多个空格,否则delimiter
命令不会运行:例如,您需要在创建event时将默认的数据库
;
更改为$$
,然后在创建事件后,您需要将数据库$$
更改回;
,如下所示。* 创建事件时必须选择数据库:但是,如果您在创建事件时没有将默认值
;
更改为类似$$
的值,则会出现如下所示的错误: