日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql存储过程中as_Mysql存储过程中的delimiter

發(fā)布時間:2024/10/5 数据库 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql存储过程中as_Mysql存储过程中的delimiter 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這個命令與存儲過程沒什么關系吧。

其實就是告訴mysql解釋器,該段命令是否已經(jīng)結束了,mysql是否可以執(zhí)行了。

默認情況下,delimiter是分號;。在命令行客戶端中,如果有一行命令以分號結束,

那么回車后,mysql將會執(zhí)行該命令。如輸入下面的語句

mysql> select * from

test_table;

然后回車,那么MySQL將立即執(zhí)行該語句。

但有時候,不希望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;

默認情況下,不可能等到用戶把這些語句全部輸入完之后,再執(zhí)行整段語句。

因為mysql一遇到分號,它就要自動執(zhí)行。

即,在語句RETURN

'';時,mysql解釋器就要執(zhí)行了。

這種情況下,就需要事先把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;//

這樣只有當//出現(xiàn)之后,mysql解釋器才會執(zhí)行這段語句

例子:

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 下運行通過。

編寫了個統(tǒng)計網(wǎng)站訪問情況(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)卻不能執(zhí)行。

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:“;”

-> //

-> //

-> //

-> ;

-> ;

->

真是奇怪了!最后終于發(fā)現(xiàn)問題了,在 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 數(shù)據(jù)庫中執(zhí)行在文件中的 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存储过程中as_Mysql存储过程中的delimiter的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。