CREATE? PROCEDURE `gk_test`()
公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)公司推出貢山免費(fèi)做網(wǎng)站回饋大家。
COMMENT '測(cè)試數(shù)據(jù)'? -- 函數(shù)注釋
BEGIN
DECLARE done INT DEFAULT FALSE;?-- 定義遍歷數(shù)據(jù)結(jié)束標(biāo)志。非游標(biāo)變量,需要定義在游標(biāo)變量前
DECLARE m_id CHAR(32);?-- 定義接收游標(biāo)數(shù)據(jù)中id變量
DECLARE m_or VARCHAR(255);?--?定義接收游標(biāo)數(shù)據(jù)中orderno變量
DECLARE m_c INT(11);??--?定義接收游標(biāo)數(shù)據(jù)中count變量
DECLARE m_soult CURSOR FOR SELECT `id`, `orderno`, count(*) t FROM hb_shipper_order GROUP BY orderno HAVING t 1;???-- 定義游標(biāo)變量,即接收查詢結(jié)果集
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;??-- 將結(jié)束標(biāo)志綁定到游標(biāo)
OPEN m_soult;? ??-- 打開游標(biāo)
read_loop:LOOP? ?-- 開始循環(huán)。這個(gè)是mysql 3種循環(huán)中的1種。
FETCH m_soult INTO m_id,m_or,m_c;???-- 提取游標(biāo)數(shù)據(jù)
IF done THEN? ?-- 判斷,當(dāng)為true時(shí)
LEAVE read_loop;? ?-- 跳出循環(huán)
END IF;
-- 處理事 自己想處理的事
UPDATE `hb_shipper_waybill` SET
ordernos = REPLACE (`ordernos`, m_or, CONCAT(m_or,'-2')),
goodsname = REPLACE (`goodsname`, m_or, CONCAT(m_or,'-2'))
WHERE `id` IN ( SELECT `waybillid` FROM `hb_shipper_order_waybill_relation` WHERE orderid = m_id);
UPDATE `hb_shipper_order` SET orderno = CONCAT(m_or,'-2') WHERE id = m_id;
END LOOP;? -- 結(jié)束循環(huán)
-- 關(guān)閉游標(biāo)
CLOSE m_soult;
END
上圖:
DEMO: 2? ? // 通過 存儲(chǔ)過程,處理? copy 數(shù)據(jù)并處理對(duì)應(yīng)數(shù)據(jù)關(guān)系
delimiter $$
DROP PROCEDURE IF EXISTS gk;
CREATE DEFINER =? PROCEDURE `gk`(IN pname varchar(255))
COMMENT '測(cè)試'
BEGIN
DECLARE new_id CHAR(32);
DECLARE m_id CHAR(32);
DECLARE new_noids VARCHAR(255);
DECLARE done INT DEFAULT 0;
DECLARE m_result CURSOR FOR select id from `xxx`;
DECLARE m_result2 CURSOR FOR select id from `xxx`;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TABLE IF EXISTS `xxx`;
CREATE TABLE `xxx` (
`id` char(32) NOT NULL COMMENT 'ID',
`subsystem` char(32) NOT NULL COMMENT '',
`name` varchar(20) NOT NULL COMMENT '',
`type` varchar(15) NOT NULL COMMENT '',
`url` varchar(200) DEFAULT NULL COMMENT '',
`icon` varchar(20) DEFAULT NULL COMMENT '',
`target` varchar(10) NOT NULL DEFAULT '_self' COMMENT '',
`method` mediumtext COMMENT '',
`orderby` smallint(3) NOT NULL DEFAULT '0' COMMENT '',
`parentid` char(32) NOT NULL DEFAULT '0' COMMENT '',
`relateid` char(32) NOT NULL COMMENT '',
`isopen` tinyint(1) NOT NULL DEFAULT '1' COMMENT '',
`nodeids` varchar(255) DEFAULT NULL COMMENT '',
`nodenum` smallint(3) NOT NULL DEFAULT '0' COMMENT '',
`createtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '',
`createuser` char(32) NOT NULL DEFAULT '0' COMMENT '',
`updatetime` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '',
`udateuser` char(32) NOT NULL DEFAULT '0' COMMENT '',
`deleted` tinyint(1) DEFAULT '0' COMMENT '',
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '',
`isdefault` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '',
? ? ? ? ? ? `isdisable` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '',
`projecttype` varchar(255) NOT NULL COMMENT '',
? ? ????PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
INSERT INTO `xxxx` SELECT * FROM `aaa` WHERE `projecttype` = 'T';
UPDATE `xxx` SET `projecttype` = pname;
OPEN m_result;
REPEAT
FETCH m_result INTO m_id;
SET new_id = UPPER(REPLACE(UUID(),'-',''));
UPDATE `xxx` SET `id` = new_id WHERE `id` = m_id;
UPDATE `xxx` SET `parentid` = new_id WHERE `parentid` = m_id;
UNTIL done END REPEAT;
CLOSE m_result;
SET done = 0;
OPEN m_result2;
REPEAT
FETCH m_result2 INTO m_id;
SELECT CONCAT(',', GROUP_CONCAT(`id`)) INTO new_noids FROM `xxx` WHERE `parentid` = m_id;
UPDATE `xxx` SET `nodeids` = new_noids WHERE `id` = m_id;
UNTIL done END REPEAT;????
CLOSE m_result2;
INSERT INTO `aaa` SELECT * FROM `xxx`;
DROP TABLE IF EXISTS xxx;
END $$
delimiter ;
從字面可以這么理解什么是游標(biāo),游標(biāo)就像是水面上漂浮的一個(gè)標(biāo)記,這個(gè)標(biāo)記可以來回游動(dòng),一會(huì)游到這里一會(huì)游到那里,這里的河水可以理解為是數(shù)據(jù)的集合,這個(gè)標(biāo)記就是在這些數(shù)據(jù)間來回游動(dòng)。
為什么 MySQL 會(huì)有游標(biāo)這個(gè)概念,由于 SQL 語言是面向集合的語句,它每次查詢出來都是一堆數(shù)據(jù)的集合,沒有辦法對(duì)其中一條記錄進(jìn)行單獨(dú)的處理。如果要對(duì)每條記錄進(jìn)行單獨(dú)處理就需要游標(biāo)。
游標(biāo)其實(shí)就像是編程語言中的 for/foreach 循環(huán),把一個(gè)數(shù)組(數(shù)據(jù)的集合)中每條數(shù)據(jù)一條一條地循環(huán)出來,然后你在 for/foreach 循環(huán)中使用判斷語句對(duì)你感興趣的數(shù)據(jù)進(jìn)行處理。
哪里可以使用游標(biāo)呢,函數(shù),存儲(chǔ)過程,觸發(fā)器中都可以使用。
說完概念,就來看下游標(biāo)的固定寫法。不管概念是否理解,記住下面的固定模式也可以完成搬磚任務(wù)。
1、聲明游標(biāo)
SELECT 語句就是正常的查詢語句,例如:SELECT id,age FROM table;
2、打開游標(biāo)
在打開游標(biāo)之前,游標(biāo)定義的 SQL 語句是不執(zhí)行的。
3、取出記錄
將當(dāng)前的記錄數(shù)據(jù)存入變量。
當(dāng) FETCH 沒有找到記錄時(shí)會(huì)拋出異常,異常的定義需要下面的 HANDLER FOR 語句。
聲明游標(biāo)語句中的 SELECT 如果有多個(gè)字段,INTO 后面需要多個(gè)變量進(jìn)行接收。
4、設(shè)置結(jié)束條件
這個(gè)語句的作用是指定一個(gè)條件,告訴程序所有數(shù)據(jù)已經(jīng)循環(huán)完畢,可以結(jié)束了。由于游標(biāo)是使用 WHILE 循環(huán)進(jìn)行每條數(shù)據(jù)的讀取,就需要給 WHILE 一個(gè)結(jié)束條件。
處理種類:可以是, EXIT 立即結(jié)束。CONTINUE 繼續(xù)下面的處理。
異常的類型:一般指定為 NOT FOUND ,意思是沒有找到任何數(shù)據(jù)。
異常發(fā)生時(shí)的處理:當(dāng)異常發(fā)生時(shí)需要做的事情,這里一般改變一個(gè)變量的值來記錄異常已經(jīng)發(fā)生了,如如 SET flat = 1 詳細(xì)用法查看下面的例子。
5、關(guān)閉游標(biāo)
實(shí)戰(zhàn)代碼:
完畢,看懂沒,如果沒看懂沒關(guān)系,游標(biāo)處理是一套固定的格式,按照上面例子中固定的格式套入到你的程序就可以了。
先聲明一個(gè)游標(biāo),語法:
DECLARE v_1 VARCHAR(16);
DECLARE v_2 VARCHAR(16);
DECLARE c_XXX CURSOR FOR
SELECT c_1, c_2
FROM t_1;
同時(shí)聲明一個(gè)布爾型的變量FOUND,當(dāng)循環(huán)的條件不成立時(shí),結(jié)束循環(huán)用的。
DECLARE FOUND BOOLEAN DEFAULT TRUE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET FOUND = FALSE;
在使用游標(biāo)的時(shí)候,要先打開游標(biāo),語法:OPEN c_XXX;
使用的時(shí)候,要先打開游標(biāo),取出第一條數(shù)據(jù),語法: FETCH c_XXX INTO v_1, v_2;
然后才開始執(zhí)行循環(huán),語法:WHILE FOUND DO
執(zhí)行需要執(zhí)行的語句;
取下一條數(shù)據(jù)放到當(dāng)前游標(biāo)中,F(xiàn)ETCH c_XXX INTO v_1, v_2;
結(jié)束循環(huán),語法:END WHILE;
結(jié)束游標(biāo),語法:CLOSE c_cargo。有什么問題我們?cè)贉贤ò?。不知道你具體要問題的是什么。