转载于:http://blog.csdn.net/yuxin6866/article/details/52722913

其实就是告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了。默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。

  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这么做。在为可能输入较多的语句,且语句中包含有分号。 
如试图在命令行客户端中输入如下语句

  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换成其它符号,如//或$$。

  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解释器才会执行这段语句 .

例子

  1. mysql> delimiter //
  2. mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
  3. -> BEGIN
  4. -> SELECT COUNT(*) INTO param1 FROM t;
  5. -> END;
  6. -> //
  7. Query OK, 0 rows affected (0.00 sec)
  8. mysql> delimiter ;
  9. mysql> CALL simpleproc(@a);
  10. Query OK, 0 rows affected (0.00 sec)
  11. mysql> SELECT @a;
  12. +------+
  13. | @a |
  14. +------+
  15. | 3 |
  16. +------+
  17. 1 row in set (0.00 sec)

本文代码在 MySQL 5.0.41-community-nt 下运行通过。 
编写了个统计网站访问情况(user agent)的 MySQL 存储过程。就是下面的这段 SQL 代码。

  1. drop procedure if exists pr_stat_agent;
  2. -- call pr_stat_agent ('2008-07-17', '2008-07-18')
  3. create procedure pr_stat_agent
  4. (
  5. pi_date_from  date
  6. ,pi_date_to    date
  7. )
  8. begin
  9. -- check input
  10. if (pi_date_from is null) then
  11. set pi_date_from = current_date();
  12. end if;
  13. if (pi_date_to is null) then
  14. set pi_date_to = pi_date_from;
  15. end if;
  16. set pi_date_to = date_add(pi_date_from, interval 1 day);
  17. -- stat
  18. select agent, count(*) as cnt
  19. from apache_log
  20. where request_time >= pi_date_from
  21. and request_time <  pi_date_to
  22. group by agent
  23. order by cnt desc;
  24. end;

在 EMS SQL Manager 2005 for MySQL 这个 MySQL 图形客户端下可以顺利运行。但是在 SQLyog MySQL GUI v5.02 这个客户端就会出错。最后找到原因是没有设置好 delimiter 的问题。默认情况下,delimiter “;” 用于向 MySQL 提交查询语句。在存储过程中每个 SQL 语句的结尾都有个 “;”,如果这时候,每逢 “;” 就向 MySQL 提交的话,当然会出问题了。于是更改 MySQL 的 delimiter,上面 MySQL 存储过程就编程这样子了:

  1. delimiter //;     -- 改变 MySQL delimiter 为:“//”
  2. drop procedure if exists pr_stat_agent //
  3. -- call pr_stat_agent ('2008-07-17', '2008-07-18')
  4. create procedure pr_stat_agent
  5. (
  6. pi_date_from  date
  7. ,pi_date_to    date
  8. )
  9. begin
  10. -- check input
  11. if (pi_date_from is null) then
  12. set pi_date_from = current_date();
  13. end if;
  14. if (pi_date_to is null) then
  15. set pi_date_to = pi_date_from;
  16. end if;
  17. set pi_date_to = date_add(pi_date_from, interval 1 day);
  18. -- stat
  19. select agent, count(*) as cnt
  20. from apache_log
  21. where request_time >= pi_date_from
  22. and request_time <  pi_date_to
  23. group by agent
  24. order by cnt desc;
  25. end; //
  26. delimiter ; //   -- 改回默认的 MySQL delimiter:“;”

当然,MySQL delimiter 符号是可以自由设定的,你可以用 “/” 或者“” 等。但是 MySQL 存储过程中比较常见的用法是 “//” 和 “”。上面的这段在 SQLyog 中的代码搬到 MySQL 命令客户端(MySQL Command Line Client)却不能执行。 
真是奇怪了!最后终于发现问题了,在 MySQL 命令行下运行 “delimiter //; ” 则 MySQL 的 delimiter 实际上是 “//;”,而不是我们所预想的 “//”。其实只要运行指令 “delimiter //” 就 OK 了。

  1. mysql> delimiter //     -- 末尾不要符号 “;”
  2. mysql>
  3. mysql> drop procedure if exists pr_stat_agent //
  4. Query OK, 0 rows affected (0.00 sec)
  5. mysql>
  6. mysql> -- call pr_stat_agent ('2008-07-17', '2008-07-18')
  7. mysql>
  8. mysql> create procedure pr_stat_agent
  9. -> (
  10. ->    pi_date_from  date
  11. ->   ,pi_date_to    date
  12. -> )
  13. -> begin
  14. ->    -- check input
  15. ->    if (pi_date_from is null) then
  16. ->       set pi_date_from = current_date();
  17. ->    end if;
  18. ->
  19. ->    if (pi_date_to is null) then
  20. ->       set pi_date_to = pi_date_from;
  21. ->    end if;
  22. ->
  23. ->    set pi_date_to = date_add(pi_date_from, interval 1 day);
  24. ->
  25. ->    -- stat
  26. ->    select agent, count(*) as cnt
  27. ->      from apache_log
  28. ->     where request_time >= pi_date_from
  29. ->       and request_time <  pi_date_to
  30. ->     group by agent
  31. ->     order by cnt desc;
  32. -> end; //
  33. Query OK, 0 rows affected (0.00 sec)
  34. mysql>
  35. mysql> delimiter ;  -- 末尾不要符号 “//”
  36. mysql>

顺带一提的是,我们可以在 MySQL 数据库中执行在文件中的 SQL 代码。例如,我把上面存储过程的代码放在文件 d:\pr_stat_agent.sql 中。可以运行下面的代码建立存储过程。

  1. mysql> source d:\pr_stat_agent.sql
  2. Query OK, 0 rows affected (0.00 sec)
  3. Query OK, 0 rows affected (0.00 sec)

source 指令的缩写形式是:“\.”

  1. mysql> \. d:\pr_stat_agent.sql
  2. Query OK, 0 rows affected (0.00 sec)
  3. Query OK, 0 rows affected (0.00 sec)

可见 MySQL 的客户端工具在有些地方是各自为政,各有各的一套。

MySql中 delimiter 详解的更多相关文章

  1. 【SQL注入】mysql中information_schema详解

    在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库.其中保存着关于MySQL服务器所维护的所有其他数据库的信息.如数据库名,数据库的表,表栏的数据类型与访问 ...

  2. MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)

    原文地址:http://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是 ...

  3. Mysql中sql_mode详解

    阅读目录 简介 sql_mode常用值 session与global 简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进 ...

  4. MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)

    悲观锁: 顾名思义,很悲观,就是每次拿数据的时候都认为别的线程会修改数据,所以在每次拿的时候都会给数据上锁.上锁之后,当别的线程想要拿数据时,就会阻塞,直到给数据上锁的线程将事务提交或者回滚.传统的关 ...

  5. mysql中explain详解

    explain语法 有两种用法: 1.EXPLAIN tbl_name    2.EXPLAIN [EXTENDED] SELECT select_options 为了更好的说明它,我们需要建两张表, ...

  6. MySQL数据库优化详解(收藏)

    MySQL数据库优化详解 mysql表复制 复制表结构+复制表数据mysql> create table t3 like t1;mysql> insert into t3 select * ...

  7. MySQL 联合索引详解

    MySQL 联合索引详解   联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...

  8. MySQL关闭过程详解和安全关闭MySQL的方法

    MySQL关闭过程详解和安全关闭MySQL的方法 www.hongkevip.com 时间: -- : 阅读: 整理: 红客VIP 分享到: 红客VIP(http://www.hongkevip.co ...

  9. 【转】Nginx+php-fpm+MySQL分离部署详解

    转:http://www.linuxidc.com/Linux/2015-07/120580.htm Nginx+php-fpm+MySQL分离部署详解 [日期:2015-07-26] 来源:Linu ...

随机推荐

  1. zookeeper安装教程

    zookeeper  一.单机安装 1.1 下载 1.2 安装 1.3 配置 1.4 启动和停止 二.伪集群模式 2.1 zookeeper1配置 2.2 zookeeper2配置 2.3 zooke ...

  2. Maya API Test

    import maya.OpenMaya as OpenMaya import maya.OpenMayaMPx as OpenMayaMPx sl = OpenMaya.MSelectionList ...

  3. 【转】Python基础-封装与扩展、静态方法和类方法

    [转]Python基础-封装与扩展.静态方法和类方法 一.封装与扩展 封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码:而外部使用者只知道一个接口(函数),只要接口(函数 ...

  4. HardNet解读

    论文:Working hard to know your neighbor’s margins: Local descriptor learning loss  为什么介绍此文:这篇2018cvpr文 ...

  5. Python-字符串的常用操作

    name = "my name is irving and i am 22 years old!" #开头字母大写 print(name.capitalize()) #统计某字符个 ...

  6. GAN_李弘毅讲解

    GAN_李弘毅讲解: 上式中,xi从data中sample的一部分,现在的目的就是最大化这个似然函数,使得Generator最可能产生data中的这些sample: 上式中之所以如此设计V函数,是为了 ...

  7. 设计模式C++学习笔记之二十(完结篇 & 面向对象原则)设计模式C++实例下载

      Prototype(原型模式) 20.1.解释 概念:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. main(),客户 ICloneableNow,只有一个接口Clone CM ...

  8. HDU - 2665 Kth number 主席树/可持久化权值线段树

    题意 给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个 题解: 写法很多,主席树是最常用的一种之一 除此之外有:划分树,莫队分块,平衡树等 主席树的定义其实挺模糊, 一般认为就是可持久 ...

  9. Golang -- range小坑铭记

    废话少叙,先上一段代码,猜猜预期的效果. package main import ( "fmt" ) type student struct { Name string Age i ...

  10. appium+java(四)微信公众号自动化测试实践

    前言 随着手机阅读的普遍应用,微信公众号阅读,更为普遍,微信和qq一样,都是基于腾讯自研X5内核,不是google原生webview(其实就是进行了二次定制).实质上也是混合应用的一种,现在很多app ...