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小时内删除。