`
wander312
  • 浏览: 215453 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

MySql中delimiter的作用是什么?

阅读更多
MYSQL导出一个SQL后:
DELIMITER $$
DROP TRIGGER IF EXISTS `updateegopriceondelete`$$
CREATE
    TRIGGER `updateegopriceondelete` AFTER  DELETE ON  `customerinfo`
    FOR EACH ROW BEGIN
DELETE FROM egoprice  WHERE customerId=OLD.customerId;
    END$$
DELIMITER ;

其中DELIMITER 定好结束符为"$$", 然后最后又定义为";", MYSQL的默认结束符为";".



详细解释:

<br/>
其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。
默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,
那么回车后,mysql将会执行该命令。如输入下面的语句
mysql> select * from test_table;
然后回车,那么MySQL将立即执行该语句。

但有时候,不希望MySQL这么做。在为可能输入较多的语句,且语句中包含有分号。
如试图在命令行客户端中输入如下语句
mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT)
mysql>     RETURNS varchar(255)
mysql> BEGIN
mysql> IF ISNULL(S) THEN
mysql>     RETURN '';
mysql> ELSEIF N<15 THEN
mysql>     RETURN LEFT(S, N);
mysql> ELSE
mysql>     IF CHAR_LENGTH(S) <=N THEN
mysql>    RETURN S;
mysql>     ELSE
mysql>    RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5));
mysql>     END IF;
mysql> END IF;
mysql> END;
默认情况下,不可能等到用户把这些语句全部输入完之后,再执行整段语句。
因为mysql一遇到分号,它就要自动执行。
即,在语句RETURN '';时,mysql解释器就要执行了。
这种情况下,就需要事先把delimiter换成其它符号,如//或$$。
mysql> delimiter //
mysql> CREATE FUNCTION `SHORTEN`(S VARCHAR(255), N INT)
mysql>     RETURNS varchar(255)
mysql> BEGIN
mysql> IF ISNULL(S) THEN
mysql>     RETURN '';
mysql> ELSEIF N<15 THEN
mysql>     RETURN LEFT(S, N);
mysql> ELSE
mysql>     IF CHAR_LENGTH(S) <=N THEN
mysql>    RETURN S;
mysql>     ELSE
mysql>    RETURN CONCAT(LEFT(S, N-10), '...', RIGHT(S, 5));
mysql>     END IF;
mysql> END IF;
mysql> END;//
这样只有当//出现之后,mysql解释器才会执行这段语句


例子:

mysql> delimiter //

mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END;
-> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @a;
+------+
| @a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)






本文代码在 MySQL 5.0.41-community-nt 下运行通过。

编写了个统计网站访问情况(user agent)的 MySQL 存储过程。就是下面的这段 SQL 代码。

drop procedure if exists pr_stat_agent;

-- call pr_stat_agent ('2008-07-17', '2008-07-18')

create procedure pr_stat_agent
(
   pi_date_from  date
  ,pi_date_to    date
)
begin
   -- check input
   if (pi_date_from is null) then
      set pi_date_from = current_date();
   end if;

   if (pi_date_to is null) then
      set pi_date_to = pi_date_from;
   end if;

   set pi_date_to = date_add(pi_date_from, interval 1 day);

   -- stat
   select agent, count(*) as cnt
     from apache_log
    where request_time >= pi_date_from
      and request_time <  pi_date_to
    group by agent
    order by cnt desc;
end;

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

delimiter //;     -- 改变 MySQL delimiter 为:“//”

drop procedure if exists pr_stat_agent //

-- call pr_stat_agent ('2008-07-17', '2008-07-18')

create procedure pr_stat_agent
(
   pi_date_from  date
  ,pi_date_to    date
)
begin
   -- check input
   if (pi_date_from is null) then
      set pi_date_from = current_date();
   end if;

   if (pi_date_to is null) then
      set pi_date_to = pi_date_from;
   end if;

   set pi_date_to = date_add(pi_date_from, interval 1 day);

   -- stat
   select agent, count(*) as cnt
     from apache_log
    where request_time >= pi_date_from
      and request_time <  pi_date_to
    group by agent
    order by cnt desc;
end; //

delimiter ; //   -- 改回默认的 MySQL delimiter:“;”

当然,MySQL delimiter 符号是可以自由设定的,你可以用 “/” 或者“$$” 等。但是 MySQL 存储过程中比较常见的用法是 “//” 和 “$$”。上面的这段在 SQLyog 中的代码搬到 MySQL 命令客户端(MySQL Command Line Client)却不能执行。

mysql> delimiter //;     -- 改变 MySQL delimiter 为:“//”
mysql>
mysql> drop procedure if exists pr_stat_agent //
    ->
    -> -- call pr_stat_agent ('2008-07-17', '2008-07-18')
    ->
    -> create procedure pr_stat_agent
    -> (
    ->    pi_date_from  date
    ->   ,pi_date_to    date
    -> )
    -> begin
    ->    -- check input
    ->    if (pi_date_from is null) then
    ->       set pi_date_from = current_date();
    ->    end if;
    ->
    ->    if (pi_date_to is null) then
    ->       set pi_date_to = pi_date_from;
    ->    end if;
    ->
    ->    set pi_date_to = date_add(pi_date_from, interval 1 day);
    ->
    ->    -- stat
    ->    select agent, count(*) as cnt
    ->      from apache_log
    ->     where request_time >= pi_date_from
    ->       and request_time <  pi_date_to
    ->     group by agent
    ->     order by cnt desc;
    -> end; //
    ->
    -> delimiter ; //   -- 改回默认的 MySQL delimiter:“;”
    -> //
    -> //
    -> //
    -> ;
    -> ;
    ->

真是奇怪了!最后终于发现问题了,在 MySQL 命令行下运行 “delimiter //; ” 则 MySQL 的 delimiter 实际上是 “//;”,而不是我们所预想的 “//”。其实只要运行指令 “delimiter //” 就 OK 了。

mysql> delimiter //     -- 末尾不要符号 “;”
mysql>
mysql> drop procedure if exists pr_stat_agent //
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> -- call pr_stat_agent ('2008-07-17', '2008-07-18')
mysql>
mysql> create procedure pr_stat_agent
    -> (
    ->    pi_date_from  date
    ->   ,pi_date_to    date
    -> )
    -> begin
    ->    -- check input
    ->    if (pi_date_from is null) then
    ->       set pi_date_from = current_date();
    ->    end if;
    ->
    ->    if (pi_date_to is null) then
    ->       set pi_date_to = pi_date_from;
    ->    end if;
    ->
    ->    set pi_date_to = date_add(pi_date_from, interval 1 day);
    ->
    ->    -- stat
    ->    select agent, count(*) as cnt
    ->      from apache_log
    ->     where request_time >= pi_date_from
    ->       and request_time <  pi_date_to
    ->     group by agent
    ->     order by cnt desc;
    -> end; //
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> delimiter ;  -- 末尾不要符号 “//”
mysql>

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

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

Query OK, 0 rows affected (0.00 sec)

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

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

Query OK, 0 rows affected (0.00 sec)

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



分享到:
评论

相关推荐

    详解 Mysql中的delimiter定义及作用

    初学mysql时,可能不太明白delimiter的真正用途,delimiter在mysql很多地方出现,比如存储过程、触发器、函数等。 学过oracle的人,再来学mysql就会感到很奇怪,百思不得其解。 其实就是告诉mysql解释器,该段命令...

    MySql中 delimiter 详解.docx

    在MySQL中,`delimiter`命令是用来设定SQL语句的结束符的,它的主要作用是告诉MySQL解释器何时一个完整的命令结束,从而可以开始执行。在默认情况下,MySQL使用分号(;)作为命令的终止符。这意味着当你在MySQL...

    MySql delimiter的作用是什么

    它的主要作用是告诉MySQL解析器何时一个完整的命令或语句结束,从而可以被执行。默认情况下,MySQL使用分号(;)作为语句的结束符。当你在MySQL命令行客户端中输入一条SQL语句,如果该语句以分号结尾,按下回车键后...

    mysql与oracle差异总结

    MySql 使用 DELIMITER 语句来标记函数的开始和结束,而 Oracle 使用 CREATE FUNCTION 语句。在 MySql 中,同时还需要指定函数的定义者和字符集。 2. 变量声明 在 MySql 中,所有的声明必须在函数体之前,全局变量...

    Mysql中文汉字转拼音的实现(每个汉字转换全拼)

    在MySQL中实现中文汉字转拼音的功能,主要是为了方便在数据库查询和数据分析时处理中文文本,尤其是在没有全文索引或者需要进行复杂模糊匹配时。以下是一个简单的实现方法,它利用自定义函数来完成这一任务。 首先...

    mysql中造3千条数据(3种方法)

    MySQL 中造 3000 条数据的三个方法 MySQL 是一种非常流行的关系型数据库管理系统,它提供了多种方式来快速生成大量数据。本文将介绍三种方法来在 MySQL 中造 3000 条数据。 方法一:使用存储过程 存储过程是一种...

    mysql 基本命令,及java中访问mysql

    MySQL是世界上最流行的开源关系型数据库管理系统之一,广泛应用于各种规模的应用程序中,包括Web应用程序、企业内部系统等。本文将详细介绍MySQL的一些基本命令以及如何在Java中访问MySQL数据库。 1. **启动MySQL...

    MySQL中创建procedure,function,trigger

    MySQL 中创建存储过程、函数和触发器 MySQL 中创建存储过程、函数和触发器是数据库管理系统中非常重要的组成部分。它们可以帮助开发者简化数据库操作、提高数据库性能和安全性。本文将详细介绍 MySQL 中创建存储...

    MySQL基础PDF版

    数据库的主要作用是安全地保存数据,并支持数据的增删改查。 - **数据库类型**:分为关系型数据库(如MySQL、Oracle、SQL Server等)和非关系型数据库(如Redis、MongoDB)。关系型数据库通过外键关联表与表之间的...

    mysql 面试题.pdf

    8. **解释MySQL中的二进制日志(Binary Log)的作用及其如何用于数据恢复。** - **二进制日志** 记录了对数据库所做的所有更改。 - 可以通过重放二进制日志来恢复数据。 #### 四、概念性和理论性问题 1. **解释...

    MySQL入门+进阶资源合集.pdf

    ### MySQL入门+进阶资源合集 #### 一、MySQL基础知识与入门 ##### 1.1 MySQL基础概念 - **数据库(Database)**:是用于存储数据的逻辑容器,它能够高效地管理...希望这些内容能够帮助你在MySQL的学习旅程中取得进步!

    mysql调用存储过程

    MySQL存储过程是数据库管理系统中一组为了完成特定功能的SQL语句集,它可以被命名、保存并在需要时调用,极大地提高了数据库开发效率和程序的可维护性。在Java应用程序中,我们经常使用JDBC(Java Database ...

    MSql与Mysql的转换

    MS SQL和MySQL在编写这些数据库对象时的语法有所不同,例如,MS SQL使用`CREATE PROCEDURE`,而MySQL使用`DELIMITER`和`END`来定义存储过程。转换时,这些语句需要按MySQL的语法重新编写。 索引也是转换中的关键...

    mysql递归查询.doc

    MySQL 递归查询是指在 MySQL 数据库中使用递归函数来实现树形结构数据的查询,例如部门表中某个部门的所有下属部分或者某个部分的所有上级部门。 在 MySQL 中实现递归查询需要使用自定义函数(Stored Function),...

    MySql 中查询树形结构的全部子项列表 Function

    在MySQL数据库中,处理树形结构的数据是一项常见的任务,特别是在构建层级关系如组织架构、菜单系统或者分类目录时。本文将深入探讨如何在MySQL中查询树形结构的全部子项列表,结合提供的`MySql_Link_Function.sql`...

    Oracle到mysql的迁移步骤及各种注意事项_数据库.pdf

    在 MySQL 中,存储过程的格式是使用 `DELIMITER` 语句来定义,例如: ```sql DELIMITER $$ CREATE PROCEDURE `pkg_ypgl.prc_ypsc`(prm_ypbm VARCHAR(20), OUT prm_AppCode VARCHAR(20), OUT prm_ErrorMsg VARCHAR...

    mysql 计算字符串相似度

    本文将详细介绍如何在 MySQL 中创建一个自定义函数 `sfn_GetSimilar_Rate` 来计算两个中文字符串的相似度,并基于此相似度进行排序。 #### 函数设计与实现 本节将详细介绍 `sfn_GetSimilar_Rate` 函数的设计与实现...

    MySQL存储过程的异常处理方法

    首先,我们注意到在创建存储过程`myProc`时,使用了`delimiter $$`来改变MySQL客户端的语句分隔符,这是为了在存储过程中使用多个分号(;)而不会导致命令提前结束。存储过程的定义如下: ```sql CREATE PROCEDURE ...

Global site tag (gtag.js) - Google Analytics