在數(shù)據(jù)庫中,游標(biāo)是一個(gè)十分重要的概念。游標(biāo)提供了一種對從表中檢索出的數(shù)據(jù)進(jìn)行操作的靈活手段,就本質(zhì)而言,游標(biāo)實(shí)際上是一種能從包括多條數(shù)據(jù)記錄的結(jié)果集中每次提取一條記錄的機(jī)制。游標(biāo)總是與一條SQL 選擇語句相關(guān)聯(lián)因?yàn)橛螛?biāo)由結(jié)果集(可以是零條、一條或由相關(guān)的選擇語句檢索出的多條記錄)和結(jié)果集中指向特定記錄的游標(biāo)位置組成。當(dāng)決定對結(jié)果集進(jìn)行處理時(shí),必須聲明一個(gè)指向該結(jié)果集的游標(biāo)。如果曾經(jīng)用 C 語言寫過對文件進(jìn)行處理的程序,那么游標(biāo)就像您打開文件所得到的文件句柄一樣,只要文件打開成功,該文件句柄就可代表該文件。對于游標(biāo)而言,其道理是相同的??梢娪螛?biāo)能夠?qū)崿F(xiàn)按與傳統(tǒng)程序讀取平面文件類似的方式處理來自基礎(chǔ)表的結(jié)果集,從而把表中數(shù)據(jù)以平面文件的形式呈現(xiàn)給程序。
創(chuàng)新互聯(lián)主營環(huán)江網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都app軟件開發(fā),環(huán)江h(huán)5重慶小程序開發(fā)搭建,環(huán)江網(wǎng)站營銷推廣歡迎環(huán)江等地區(qū)企業(yè)咨詢
我們知道關(guān)系數(shù)據(jù)庫管理系統(tǒng)實(shí)質(zhì)是面向集合的,在MS SQL SERVER 中并沒有一種描述表中單一記錄的表達(dá)形式,除非使用where 子句來限制只有一條記錄被選中。因此我們必須借助于游標(biāo)來進(jìn)行面向單條記錄的數(shù)據(jù)處理。由此可見,游標(biāo)允許應(yīng)用程序?qū)Σ樵冋Z句select 返回的行結(jié)果集中每一行進(jìn)行相同或不同的操作,而不是一次對整個(gè)結(jié)果集進(jìn)行同一種操作;它還提供對基于游標(biāo)位置而對表中數(shù)據(jù)進(jìn)行刪除或更新的能力;而且,正是游標(biāo)把作為面向集合的數(shù)據(jù)庫管理系統(tǒng)和面向行的程序設(shè)計(jì)兩者聯(lián)系起來,使兩個(gè)數(shù)據(jù)處理方式能夠進(jìn)行溝通。
在數(shù)據(jù)庫開發(fā)過程中,當(dāng)你檢索的數(shù)據(jù)只是一條記錄時(shí),你所編寫的事務(wù)語句代碼往往使用SELECT INSERT 語句。但是我們常常會遇到這樣情況,即從某一結(jié)果集中逐一地讀取一條記錄。那么如何解決這種問題呢?游標(biāo)為我們提供了一種極為優(yōu)秀的解決方案——那就是使用游標(biāo)。
從字面可以這么理解什么是游標(biāo),游標(biāo)就像是水面上漂浮的一個(gè)標(biāo)記,這個(gè)標(biāo)記可以來回游動,一會游到這里一會游到那里,這里的河水可以理解為是數(shù)據(jù)的集合,這個(gè)標(biāo)記就是在這些數(shù)據(jù)間來回游動。
為什么 MySQL 會有游標(biāo)這個(gè)概念,由于 SQL 語言是面向集合的語句,它每次查詢出來都是一堆數(shù)據(jù)的集合,沒有辦法對其中一條記錄進(jìn)行單獨(dú)的處理。如果要對每條記錄進(jìn)行單獨(dú)處理就需要游標(biāo)。
游標(biāo)其實(shí)就像是編程語言中的 for/foreach 循環(huán),把一個(gè)數(shù)組(數(shù)據(jù)的集合)中每條數(shù)據(jù)一條一條地循環(huán)出來,然后你在 for/foreach 循環(huán)中使用判斷語句對你感興趣的數(shù)據(jù)進(jìn)行處理。
哪里可以使用游標(biāo)呢,函數(shù),存儲過程,觸發(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í)會拋出異常,異常的定義需要下面的 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)處理是一套固定的格式,按照上面例子中固定的格式套入到你的程序就可以了。
MySQL 存儲過程中,使用游標(biāo)查詢,返回的是結(jié)果集時(shí),如何查看調(diào)用存儲過程輸出結(jié)果呢?
解決方案:存儲過程不返回?cái)?shù)據(jù),但它能創(chuàng)建和填充另一個(gè)表。所以在存儲過程運(yùn)行中創(chuàng)建臨時(shí)表。該臨時(shí)表將保存存儲過程中生成的結(jié)果集,在遍歷游標(biāo)時(shí),用insert保存每條數(shù)據(jù)到臨時(shí)表中。后續(xù)調(diào)用時(shí)可以用select語句查詢臨時(shí)表中的存儲過程運(yùn)行結(jié)果。
以下有 三種方式 使用游標(biāo)創(chuàng)建一個(gè)存儲過程,統(tǒng)計(jì)某一部門下的員工信息
方法一:Loop循環(huán)
調(diào)用存儲過程:
方法二:While 循環(huán)
調(diào)用存儲過程:
方法三:REPEAT 循環(huán)
調(diào)用存儲過程:
上述三種實(shí)現(xiàn)方法在測試過程中遇到下述問題。
調(diào)用存儲過程查詢臨時(shí)表輸出結(jié)果時(shí),會發(fā)現(xiàn)多循環(huán)了一次,像這樣:
解決方法:
在遍歷游標(biāo)查詢結(jié)果時(shí),先判斷游標(biāo)的結(jié)束標(biāo)志(done) 是否是為1,如果不是1,則向臨時(shí)表中插入數(shù)據(jù)。
本文實(shí)例講述了Mysql存儲過程中游標(biāo)的用法。分享給大家供大家參考。具體如下:
1.
批量插入商戶路由關(guān)聯(lián)數(shù)據(jù):
DELIMITER
$$
USE
`mmm_mac`$$
DROP
PROCEDURE
IF
EXISTS
`批量插入商戶路由關(guān)聯(lián)數(shù)據(jù)`$$
CREATE
DEFINER=`root`@`%`
PROCEDURE
`批量插入商戶路由關(guān)聯(lián)數(shù)據(jù)`()
BEGIN
DECLARE
v_partner_no
VARCHAR(32);
DECLARE
v_partner_id
INT(11);
DECLARE
v_sc_pid
INT(11);
DECLARE
v_mac_no
VARCHAR(32);
DECLARE
v_mac_addr
VARCHAR(32);
DECLARE
n_mac_no
BIGINT;
DECLARE
n_mac_addr
BIGINT;
DECLARE
n_mac_addr_str
VARCHAR(32);
DECLARE
done
INT;
#取得商戶數(shù)據(jù)
DECLARE
cur_partnerlist
CURSOR
FOR
SELECT
comp_id,
partner_no,
sc_pid
FROM
mmm_partner.anl_partner;
SET
n_mac_no
=
100000000;
SET
n_mac_addr
=
1000000000;
OPEN
cur_partnerlist;
REPEAT
FETCH
cur_partnerlist
INTO
v_partner_id,v_partner_no,v_sc_pid;
SET
v_mac_no
=
CONCAT('MAC',v_sc_pid,n_mac_no);
SET
n_mac_addr_str
=
CONCAT(SUBSTR(n_mac_addr,1,2),':',SUBSTR(n_mac_addr,3,2),':',SUBSTR(n_mac_addr,5,2),':',SUBSTR(n_mac_addr,7,2),':',SUBSTR(n_mac_addr,9,2));
SET
v_mac_addr
=
CONCAT('CC:',n_mac_addr_str);
SET
n_mac_no
=
n_mac_no
+
1;
SET
n_mac_addr
=
n_mac_addr
+
1;
#向t_machine_sc_config表中插入商戶關(guān)聯(lián)路由的數(shù)據(jù)
#insert
into
t_machine_sc_config(mac_no,
partner_no,
partner_id,
sc_pid,
mac_addr,
comp_id,
is_lock)
values('MAC2016000000001','44060430603381',1,4403,'C8:87:18:AB:79:66',1,1);
INSERT
INTO
t_machine_sc_config(mac_no,
partner_no,
partner_id,
sc_pid,
mac_addr,
comp_id,
is_lock)
VALUES(v_mac_no,v_partner_no,v_partner_id,v_sc_pid,v_mac_addr,1,1);
UNTIL
END
REPEAT;
CLOSE
cur_partnerlist;
END$$
DELIMITER
;
2.
更新商戶表:
DELIMITER
$$
USE
`mmm_partner`$$
DROP
PROCEDURE
IF
EXISTS
`更新商戶表`$$
CREATE
DEFINER=`root`@`%`
PROCEDURE
`更新商戶表`()
BEGIN
DECLARE
v_partner_no
VARCHAR(32);
DECLARE
vpartner_no
VARCHAR(32);
DECLARE
v_partner_id
VARCHAR(32);
DECLARE
n
BIGINT;
DECLARE
partnerid_list
CURSOR
FOR
SELECT
comp_id
FROM
100msh_partner.anl_partner
WHERE
TRIM(partner_no)
=
'';
SET
vpartner_no
=
'2015415parno';
SET
n
=
10000000;
OPEN
partnerid_list;
REPEAT
FETCH
partnerid_list
INTO
v_partner_id;
SET
v_partner_no
=
CONCAT(vpartner_no,n);
SET
n
=
n
+
1;
UPDATE
mmm_partner.anl_partner
SET
partner_no
=
v_partner_no
WHERE
comp_id
=
v_partner_id;
UNTIL
END
REPEAT;
CLOSE
partnerid_list;
END$$
DELIMITER
;
希望本文所述對大家的mysql數(shù)據(jù)庫程序設(shè)計(jì)有所幫助。
網(wǎng)站欄目:mysql中游標(biāo)怎么使用 mysql游標(biāo)嵌套
文章轉(zhuǎn)載:http://muchs.cn/article12/dojhsgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、做網(wǎng)站、電子商務(wù)、網(wǎng)站內(nèi)鏈、網(wǎng)站建設(shè)、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)