mysql leave的作用_MySQL数据库中DELIMITER的作用
以下的文章主要是向大家描述的是MySQL數據庫中delimiter的作用是什么?我們一般都認為這個命令和存儲過程關系不大,到底是不是這樣的呢?以下的文章將會給你相關的知識,望你會有所收獲。
下面是一個存儲過程的實例: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:查詢子節點?1:查詢父節點?2:返回經過節點的父節點以及子節點。
#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,",?)");
#?循環查詢所有節點
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?;
其實就是告訴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?
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?
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?
->?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?
->?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 leave的作用_MySQL数据库中DELIMITER的作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Vue中导出Excel
- 下一篇: css --- 伸缩布局,让图片居中