mysql leave的作用_MySQL数据库中DELIMITER的作用
以下的文章主要是向大家描述的是MySQL數(shù)據(jù)庫中delimiter的作用是什么?我們一般都認(rèn)為這個(gè)命令和存儲(chǔ)過程關(guān)系不大,到底是不是這樣的呢?以下的文章將會(huì)給你相關(guān)的知識(shí),望你會(huì)有所收獲。
下面是一個(gè)存儲(chǔ)過程的實(shí)例:DELIMITER?$$
USE?`xht_ywp`$$
DROP?PROCEDURE?IF?EXISTS?`batchGetNsjgTreeList`$$
CREATE?DEFINER=`dlwy`@`%`?PROCEDURE?`batchGetNsjgTreeList`(dwCode?VARCHAR(20),rootId?VARCHAR(1000),isParent?INT,?haveSelf?INT)
BEGIN
#?isParent0:查詢子節(jié)點(diǎn)?1:查詢父節(jié)點(diǎn)?2:返回經(jīng)過節(jié)點(diǎn)的父節(jié)點(diǎn)以及子節(jié)點(diǎn)。
#haveSelf0:?不包含自身?1:包含自身a
DECLARE?nsjgIds_all?TEXT;
DECLAREtableName?VARCHAR(100);
DECLAREfieldName?VARCHAR(100);
DECLAREwhereFieldName?VARCHAR(100);
#?記錄所有的ID。
SET?nsjgIds_all?=?IF(haveSelf=1,CAST(rootId?AS?CHAR),"");
loop_start?:?LOOP
SET?fieldName?=?IF(isParent=0,'NSJGID','PARID');
SET?tableName?=?CONCAT("XH_NSJG_TB",IF(LENGTH(dwCode)>0,"_",""),dwCode);
SET?whereFieldName?=?IF(isParent>0,'NSJGID','PARID');
SET?@nsjgIds?=?CAST(rootId?AS?CHAR);
SET?@curSql?=?CONCAT("SELECT?GROUP_CONCAT(",fieldName,")?INTO?@nsjgIds?FROM?",tableName,"?WHERE?FIND_IN_SET?(",whereFieldName,",?)");
#?循環(huán)查詢所有節(jié)點(diǎn)
WHILE?LENGTH(@nsjgIds)?>?0?DO
PREPARE?stmt?FROM?@curSql;
EXECUTE?stmt?USING?@nsjgIds;
DEALLOCATE?PREPARE?stmt;
IF?@nsjgIds?IS?NOT?NULL?THEN
SET?nsjgIds_all?=?CONCAT(nsjgIds_all,IF(LENGTH(nsjgIds_all),",",""),@nsjgIds);
END?IF;
END?WHILE;
SET?isParent?=?isParent?-?2;
IF?isParent?
LEAVE?loop_start;
END?IF;
END?LOOP;
SET?@curSql?=?CONCAT("SELECT?*?FROM?",tableName,"?WHERE?NSJGID?IN?(",nsjgIds_all,")");
PREPARE?stmt?FROM?@curSql;
EXECUTE?stmt?;
DEALLOCATE?PREPARE?stmt;
END$$
DELIMITER?;
其實(shí)就是告訴MySQL解釋器,該段命令是否已經(jīng)結(jié)束了,MySQL數(shù)據(jù)庫是否可以執(zhí)行了。默認(rèn)情況下,delimiter是分號(hào);。在命令行客戶端中,如果有一行命令以分號(hào)結(jié)束,那么回車后,MySQL將會(huì)執(zhí)行該命令。如輸入下面的語句MySQL>?select?*?from?test_table;
然后回車,那么MySQL將立即執(zhí)行該語句。
但有時(shí)候,不希望MySQL這么做。在為可能輸入較多的語句,且語句中包含有分號(hào)。如試圖在命令行客戶端中輸入如下語句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;
默認(rèn)情況下,不可能等到用戶把這些語句全部輸入完之后,再執(zhí)行整段語句。因?yàn)镸ySQL一遇到分號(hào),它就要自動(dòng)執(zhí)行。即,在語句RETURN '';時(shí),MySQL數(shù)據(jù)庫解釋器就要執(zhí)行了。這種情況下,就需要事先把delimiter換成其它符號(hào),如//或$$。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;//
這樣只有當(dāng)//出現(xiàn)之后,MySQL解釋器才會(huì)執(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 下運(yùn)行通過。
編寫了個(gè)統(tǒng)計(jì)網(wǎng)站訪問情況(user agent)的 MySQL 數(shù)據(jù)庫存儲(chǔ)過程。就是下面的這段 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?
group?by?agent
order?by?cnt?desc;
end;
我在 EMS SQL Manager 2005 for MySQL 這個(gè) MySQL 圖形客戶端下可以順利運(yùn)行。但是在 SQLyog MySQL GUI v5.02 這個(gè)客戶端就會(huì)出錯(cuò)。最后找到原因是沒有設(shè)置好 delimiter 的問題。
默認(rèn)情況下,delimiter “;” 用于向 MySQL 提交查詢語句。在存儲(chǔ)過程中每個(gè) SQL 語句的結(jié)尾都有個(gè) “;”,如果這時(shí)候,每逢 “;” 就向 MySQL 提交的話,當(dāng)然會(huì)出問題了。于是更改 MySQL 的 delimiter,上面 MySQL 存儲(chǔ)過程就編程這樣子了:
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?
group?by?agent
order?by?cnt?desc;
end;?//
delimiter?;
改回默認(rèn)的 MySQL delimiter:“;”
當(dāng)然,MySQL delimiter 符號(hào)是可以自由設(shè)定的,你可以用 “/” 或者“$$” 等。但是 MySQL數(shù)據(jù)庫 存儲(chǔ)過程中比較常見的用法是 “//” 和 “$$”。上面的這段在 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?
->?group?by?agent
->?order?by?cnt?desc;
->?end;?//
->
->?delimiter?;
改回默認(rèn)的 MySQL delimiter:“;”->?//
->?//
->?//
->?;
->?;
->
真是奇怪了!最后終于發(fā)現(xiàn)問題了,在 MySQL 命令行下運(yùn)行 “delimiter //; ” 則 MySQL 的 delimiter 實(shí)際上是 “//;”,而不是我們所預(yù)想的 “//”。其實(shí)只要運(yùn)行指令 “delimiter //” 就 OK 了。
MySQL> delimiter // -- 末尾不要符號(hào) “;”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?
->?group?by?agent
->?order?by?cnt?desc;
->?end;?//
Query?OK,?0?rows?affected?(0.00?sec)
MySQL>
MySQL>?delimiter?;
末尾不要符號(hào) “//”MySQL>
順帶一提的是,我們可以在 MySQL 數(shù)據(jù)庫中執(zhí)行在文件中的 SQL 代碼。例如,我把上面存儲(chǔ)過程的代碼放在文件 d:\pr_stat_agent.sql 中。可以運(yùn)行下面的代碼建立存儲(chǔ)過程。
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數(shù)據(jù)庫的客戶端工具在有些地方是各自為政,各有各的一套。
總結(jié)
以上是生活随笔為你收集整理的mysql leave的作用_MySQL数据库中DELIMITER的作用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue中导出Excel
- 下一篇: MySQL基础入门《2》创建数据库并插入