需求:
成都創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括河間網(wǎng)站建設(shè)、河間網(wǎng)站制作、河間網(wǎng)頁(yè)制作以及河間網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,河間網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到河間省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
有三張表:Player、Consumption、Consumption_other。Player表中記錄用戶信息(playerid、origin等字段),Consumption和Consumption_other記錄用戶的消費(fèi)信息?,F(xiàn)需要根據(jù)Player表中的origin字段,分別向Consumption和Consumption_other表中插入一條消費(fèi)記錄。規(guī)定:Player表中origin=0的,將信息插入到Consumption表中;Player表中origin不為0的,將信息插入到Consumption_other表中。
方法:
使用MySQL的存儲(chǔ)過程和游標(biāo)實(shí)現(xiàn):
mysql> DELIMITER // mysql> CREATE PROCEDURE `add_consumption`() -> BEGIN -> -- 定義需要接收游標(biāo)數(shù)據(jù)的變量 -> DECLARE id int(11); -> DECLARE origin int(11); -> -- 定義遍歷數(shù)據(jù)結(jié)束標(biāo)志 -> DECLARE done BOOLEAN DEFAULT 0; -> -- 定義游標(biāo) -> DECLARE cur CURSOR FOR SELECT -> player.playerid as id, -> player.origin as origin -> FROM player; -> -- 將結(jié)束標(biāo)志綁定到游標(biāo) -> DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; -> -- 打開游標(biāo) -> OPEN cur; -> -- 關(guān)閉事務(wù)自動(dòng)提交 -> SET autocommit=0; -> -- 開始循環(huán) -> read_loop:LOOP -> -- 提取游標(biāo)中的數(shù)據(jù) -> FETCH cur INTO id,origin; -> -- 聲明何時(shí)結(jié)束循環(huán) -> IF done THEN -> LEAVE read_loop; -> END IF; -> -- 循環(huán)時(shí)的事件 -> IF origin=0 -> THEN -> INSERT INTO consumption VALUES (0,1525467600); -> ELSE -> INSERT INTO consumption_other VALUES(0,1525467600); -> END IF; -> END LOOP; -> commit; -> -- 關(guān)閉游標(biāo) -> CLOSE cur; -> END -> // mysql> DELIMITER ; mysql> call add_consumption();
存儲(chǔ)過程相關(guān):
1、創(chuàng)建存儲(chǔ)過程:
格式:
CREATE PROCEDURE 過程名([參數(shù)]) 過程體
例子:
mysql> DELIMITER // mysql> CREATE PROCEDURE `originplayer`( -> IN ori int(11), -> OUT total int(11) -> ) -> BEGIN -> select count(*) from player where origin=ori into total; -> END// mysql> DELIMITER ; mysql> call originplayer(0, @total); mysql> select @total; +--------+ | @total | +--------+ | 172 | +--------+
解析:
delimiter是分割符的意思。因?yàn)镸ySQL默認(rèn)以“;”為分割符,如果沒有聲明分割符,那么編譯器會(huì)把存儲(chǔ)過程當(dāng)作SQL語(yǔ)句進(jìn)行處理,則存儲(chǔ)過程的編譯過程會(huì)報(bào)錯(cuò)?!癲elimiter //”聲明分割符是“//”。存儲(chǔ)過程中的代碼結(jié)束之后,再次聲明“delimiter;”,將“;”作為分割符。
創(chuàng)建的存儲(chǔ)過程可能會(huì)有輸入、輸出、輸入輸出參數(shù)。本例有一個(gè)輸入?yún)?shù)“ori”,類型是int,一個(gè)輸出參數(shù)“total”,類型是int。如果有多個(gè)參數(shù),用“,”分割開。
過程體的開始、結(jié)束使用BEGIN和END進(jìn)行標(biāo)識(shí)。
MySQL稱存儲(chǔ)過程的執(zhí)行為調(diào)用,因此執(zhí)行存儲(chǔ)過程的語(yǔ)句是CALL。CALL接收存儲(chǔ)過程的名字以及需要傳遞給它的任何參數(shù)。
2、參數(shù):
存儲(chǔ)過程共有三種參數(shù)類型,INT、OUT、INOUT。形式如:CREATE PROCEDURE([[IN |OUT |INOUT ] 參數(shù)名 數(shù)據(jù)類形...])
IN輸入?yún)?shù):該參數(shù)的值必須在調(diào)用存儲(chǔ)過程時(shí)指定。如果在存儲(chǔ)過程中修改了該參數(shù)的值,該參數(shù)的值仍然是修改之前的值。
OUT輸出參數(shù):指定MySQL變量,接收調(diào)用存儲(chǔ)過程后返回的值。
INOUT輸入輸出參數(shù):調(diào)用時(shí)指定,并且可被改變和返回。
3、變量:
定義存儲(chǔ)過程局部變量:
DECLARE variable_name datatype [default value];
datatype與MySQL的數(shù)據(jù)類型一樣,如:int、float、date、varchar(length);
MySQL變量:MySQL變量一般以@開頭;
變量賦值:
SET variable_name = value
4、查詢存儲(chǔ)過程:
# 列出所有的存儲(chǔ)過程: mysql> show procedure status\G # 列出某個(gè)庫(kù)擁有的存儲(chǔ)過程: mysql> select name from mysql.proc where db='project'; # 查詢存儲(chǔ)過程的詳細(xì)信息: mysql> show create procedure project.originplayer;
5、刪除存儲(chǔ)過程:
mysql> drop procedure project.originplayer;
游標(biāo)相關(guān):
1、創(chuàng)建游標(biāo):
mysql> DELIMITER // mysql> CREATE PROCEDURE `getplayerid`() -> BEGIN -> DECLARE id int(11); -> DECLARE done BOOLEAN DEFAULT 0; -> DECLARE cur CURSOR FOR SELECT -> playerid -> FROM player; -> DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1; -> OPEN cur; -> REPEAT -> FETCH cur into id; -> UTIL done END REPEAT; -> CLOSE cur; -> END// mysql> DELIMITER ;
解析:
MySQL游標(biāo)僅用于存儲(chǔ)過程中;
DECLARE語(yǔ)句用來(lái)定義和命名游標(biāo),這里的游標(biāo)為“cur”;
OPEN和CLOSE用來(lái)打開和關(guān)閉游標(biāo)。在處理OPEN語(yǔ)句時(shí)執(zhí)行查詢,存儲(chǔ)檢索出的數(shù)據(jù)以供瀏覽。CLOSE游標(biāo)將釋放游標(biāo)占用的所有內(nèi)存和內(nèi)部資源。如果沒有明確關(guān)閉游標(biāo),MySQL會(huì)在到達(dá)END語(yǔ)句時(shí)自動(dòng)關(guān)閉游標(biāo);
在一個(gè)游標(biāo)被打開后,使用FETCH語(yǔ)句可以訪問游標(biāo)的每一行,并可以指定將數(shù)據(jù)存儲(chǔ)在什么地方。
上面例子中,F(xiàn)ETCH語(yǔ)句在REPEAT內(nèi),因此它反復(fù)執(zhí)行,直到done為真(由UTIL done END REPEAT;指定);
CONTINUE HANDLER,當(dāng)REPEAT由于沒有更多的行供循環(huán)而不能繼續(xù)時(shí)出現(xiàn)這個(gè)條件,將done設(shè)置為1,此時(shí)REPEAT終止。
2、DECLARE語(yǔ)句的次序:
DECLARE語(yǔ)句的發(fā)布存在特定的次序。用DECLARE語(yǔ)句定義的局部變量必須在定義任意游標(biāo)或句柄之前;句柄的定義必須在游標(biāo)之后。
3、重復(fù)或循環(huán):
除了在1、創(chuàng)建游標(biāo)中使用的REPEAT外,MySQL還支持循環(huán)語(yǔ)句,用來(lái)重復(fù)執(zhí)行代碼,直到使用LEAVE語(yǔ)句手動(dòng)退出為止。如下:
…… -> read_loop:LOOP -> -- 提取游標(biāo)中的數(shù)據(jù) -> FETCH cur INTO id,origin; -> -- 聲明何時(shí)結(jié)束循環(huán) -> IF done THEN -> LEAVE read_loop; -> END IF; -> -- 循環(huán)時(shí)的事件 -> IF origin=0 -> THEN -> INSERT INTO consumption VALUES (0,1525467600); -> ELSE -> INSERT INTO consumption_other VALUES(0,1525467600); -> END IF; -> END LOOP; ……