MySql中delimiter详解
其实就是告诉解释器,该段命令是否已经结束了,mysql是否可以执⾏了。默认情况下,delimiter是分号;。在命令⾏客户端中,如果有⼀⾏命令以分号结束,那么回车后,mysql将会执⾏该命令。
[sql]
1. DELIMITER $$
2. DROP TRIGGER IF EXISTS `updateegopriceondelete`$$
3. CREATE
4. TRIGGER `updateegopriceondelete` AFTER DELETE ON `customerinfo`
5. FOR EACH ROW BEGIN
6. DELETE FROM egoprice WHERE customerId=OLD.customerId;
7. END$$
8. DELIMITER ;
其中DELIMITER 定好结束符为"$$", 然后最后⼜定义为";", MYSQL的默认结束符为";".
详细解释:
其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执⾏了。
默认情况下,delimiter是分号;。在命令⾏客户端中,如果有⼀⾏命令以分号结束,
那么回车后,mysql将会执⾏该命令。如输⼊下⾯的语句
mysql> select * from test_table;
然后回车,那么MySQL将⽴即执⾏该语句。
但有时候,不希望MySQL这么做。在为可能输⼊较多的语句,且语句中包含有分号。
如试图在命令⾏客户端中输⼊如下语句
[sql]
1. mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT)
2. mysql> RETURNS varchar(255)
3. mysql> BEGIN
4. mysql> IF ISNULL(S) THEN
5. mysql> RETURN '';
6. mysql> ELSEIF N<15 THEN
7. mysql> RETURN LEFT(S, N);
8. mysql> ELSE
9. mysql> IF CHAR_LENGTH(S) <=N THEN
10. mysql> RETURN S;
11. mysql> ELSE
12. mysql> RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5));
13. mysql> END IF;
14. mysql> END IF;
15. mysql> END;
默认情况下,不可能等到⽤户把这些语句全部输⼊完之后,再执⾏整段语句。
因为mysql⼀遇到分号,它就要⾃动执⾏。
即,在语句RETURN '';时,mysql解释器就要执⾏了。
这种情况下,就需要事先把delimiter换成其它符号,如//或$$。
[sql]
1. mysql> delimiter //
2. mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT)
3. mysql> RETURNS varchar(255)
4. mysql> BEGIN
5. mysql> IF ISNULL(S) THEN
6. mysql> RETURN '';
7. mysql> ELSEIF N<15 THEN
8. mysql> RETURN LEFT(S, N);
9. mysql> ELSE
10. mysql> IF CHAR_LENGTH(S) <=N THEN
11. mysql> RETURN S;
12. mysql> ELSE
13. mysql> RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5));
14. mysql> END IF;
15. mysql> END IF;
16. mysql> END;//
这样只有当//出现之后,mysql解释器才会执⾏这段语句 .
例⼦
[sql]
1. mysql> delimiter //
2.
3. mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
4. -> BEGIN
5. -> SELECT COUNT(*) INTO param1 FROM t;
6. -> END;
7. -> //
8. Query OK, 0 rows affected (0.00 sec)
9.
10. mysql> delimiter ;
11.
12. mysql> CALL simpleproc(@a);
13. Query OK, 0 rows affected (0.00 sec)
14.
15. mysql> SELECT @a;
16. +------+
17. | @a |
18. +------+
19. | 3 |
20. +------+
21. 1 row in set (0.00 sec)
本⽂代码在 MySQL 5.0.41-community-nt 下运⾏通过。
编写了个统计⽹站访问情况(user agent)的 MySQL 存储过程。就是下⾯的这段 SQL 代码。
[sql]
1. drop procedure if exists pr_stat_agent;
2.
3. -- call pr_stat_agent ('2008-07-17', '2008-07-18')
4.
5. create procedure pr_stat_agent
6. (
7. pi_date_from date
8. ,pi_date_to date
9. )
10. begin
11. -- check input
12. if (pi_date_from is null) then
13. set pi_date_from = current_date();
14. end if;
15.
16. if (pi_date_to is null) then
17. set pi_date_to = pi_date_from;
18. end if;
19.
20. set pi_date_to = date_add(pi_date_from, interval 1 day);
21.
22. -- stat
23. select agent, count(*) as cnt
24. from apache_log
sqlyog注册码在哪输入25. where request_time >= pi_date_from
26. and request_time < pi_date_to
27. group by agent
28. order by cnt desc;
29. end;
在 EMS SQL Manager 2005 for MySQL 这个 MySQL 图形客户端下可以顺利运⾏。但是在 SQLyog MySQL GUI v5.02 这个客户端就会出错。最后到原因是没有设置好 delimiter 的问题。默认情况下,delimiter “;” ⽤于向 MySQL 提交查询语句。在存储过程中每个 SQL 语句的结尾都有个 “;”,如果这时候,每逢 “;” 就向 MySQL 提交的话,当然会出问题了。于是更改MySQL 的 delimiter,上⾯ MySQL 存储过程就编程这样⼦了:
[sql]
1. delimiter //; -- 改变 MySQL delimiter 为:“//”
2.
3. drop procedure if exists pr_stat_agent //
4.
5. -- call pr_stat_agent ('2008-07-17', '2008-07-18')
6.
7. create procedure pr_stat_agent
8. (
9. pi_date_from date
10. ,pi_date_to date
11. )
12. begin
13. -- check input
14. if (pi_date_from is null) then
15. set pi_date_from = current_date();
16. end if;
17.
18. if (pi_date_to is null) then
19. set pi_date_to = pi_date_from;
20. end if;
21.
22. set pi_date_to = date_add(pi_date_from, interval 1 day);
23.
24. -- stat
25. select agent, count(*) as cnt
26. from apache_log
27. where request_time >= pi_date_from
28. and request_time < pi_date_to
29. group by agent
30. order by cnt desc;
31. end; //
32.
33. delimiter ; // -- 改回默认的 MySQL delimiter:“;”
当然,MySQL delimiter 符号是可以⾃由设定的,你可以⽤ “/” 或者“” 等。但是 MySQL 存储过程中⽐较常见的⽤法是 “//” 和“”。上⾯的这段在 SQLyog 中的代码搬到 MySQL 命令客户端(MySQL Command Line Client)却不能执⾏。
真是奇怪了!最后终于发现问题了,在 MySQL 命令⾏下运⾏ “delimiter //; ” 则 MySQL 的 delimiter 实际上是 “//;”,⽽不是我们所预想的 “//”。其实只要运⾏指令 “delimiter //” 就 OK 了。
[sql]
1. mysql> delimiter // -- 末尾不要符号 “;”
2. mysql>
3. mysql> drop procedure if exists pr_stat_agent //
4. Query OK, 0 rows affected (0.00 sec)
5.
6. mysql>
7. mysql> -- call pr_stat_agent ('2008-07-17', '2008-07-18')
8. mysql>
9. mysql> create procedure pr_stat_agent
10. -> (
11. -> pi_date_from date
12. -> ,pi_date_to date
13. -> )
14. -> begin
15. -> -- check input
16. -> if (pi_date_from is null) then
17. -> set pi_date_from = current_date();
18. -> end if;
19. ->
20. -> if (pi_date_to is null) then
21. -> set pi_date_to = pi_date_from;
22. -> end if;
23. ->
24. -> set pi_date_to = date_add(pi_date_from, interval 1 day);
25. ->
26. -> -- stat
27. -> select agent, count(*) as cnt
28. -> from apache_log
29. -> where request_time >= pi_date_from
30. -> and request_time < pi_date_to
31. -> group by agent
32. -> order by cnt desc;
33. -> end; //
34. Query OK, 0 rows affected (0.00 sec)
35.
36. mysql>
37. mysql> delimiter ; -- 末尾不要符号 “//”
38. mysql>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论