您的当前位置:首页正文

MySql中delimiter详解

来源:个人技术集锦
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是否可以执⾏了。 默认情况下,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

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>

因篇幅问题不能全部显示,请点此查看更多更全内容