MySQL游標(biāo)詳細(xì)介紹
1、什么是游標(biāo)(或光標(biāo))
雖然我們也可以通過篩選條件 WHERE 和 HAVING,或者是限定返回記錄的關(guān)鍵字 LIMIT 返回一條記錄,但是,卻無(wú)法在結(jié)果集中像指針一樣,向前定位一條記錄、向后定位一條記錄,或者是隨意定位到某一條記錄
,并對(duì)記錄的數(shù)據(jù)進(jìn)行處理。
這個(gè)時(shí)候,就可以用到游標(biāo)。游標(biāo),提供了一種靈活的操作方式,讓我們能夠?qū)Y(jié)果集中的每一條記錄進(jìn)行定位,并對(duì)指向的記錄中的數(shù)據(jù)進(jìn)行操作的數(shù)據(jù)結(jié)構(gòu)。游標(biāo)讓 SQL 這種面向集合的語(yǔ)言有了面向過程開發(fā)的能力。
SQL 中,游標(biāo)是一種臨時(shí)的數(shù)據(jù)庫(kù)對(duì)象,可以指向存儲(chǔ)在數(shù)據(jù)庫(kù)表中的數(shù)據(jù)行指針。這里游標(biāo)充當(dāng)了指針的作用
,我們可以通過操作游標(biāo)來(lái)對(duì)數(shù)據(jù)行進(jìn)行操作MySQL中游標(biāo)可以在存儲(chǔ)過程和函數(shù)中使用
比如,我們查詢了 employees 數(shù)據(jù)表中工資高于15000的員工都有哪些:
SELECT employee_id,last_name,salary FROM employees WHERE salary > 15000;
這里我們就可以通過游標(biāo)來(lái)操作數(shù)據(jù)行,如圖所示此時(shí)游標(biāo)所在的行是“108”的記錄,我們也可以在結(jié)果集上滾動(dòng)游標(biāo),指向結(jié)果集中的任意一行。
2、如何使用游標(biāo)
游標(biāo)必須在聲明處理程序之前被聲明,并且變量和條件還必須在聲明游標(biāo)或處理程序之前被聲明。
1、聲明游標(biāo)
語(yǔ)法格式:
DECLARE 游標(biāo)名 CURSOR FOR 查詢語(yǔ)句;
要使用 SELECT 語(yǔ)句來(lái)獲取數(shù)據(jù)結(jié)果集,而此時(shí)還沒有開始遍歷數(shù)據(jù),這里 查詢語(yǔ)句代表的是 SELECT 語(yǔ)句,返回一個(gè)用于創(chuàng)建游標(biāo)的結(jié)果集
舉例:
DECLARE emp_cur CURSOR FOR SELECT employee_id,salary FROM employees;
2、打開游標(biāo)
語(yǔ)法格式:
OPEN 游標(biāo)名;
當(dāng)我們定義好游標(biāo)之后,如果想要使用游標(biāo),必須先打開游標(biāo)。打開游標(biāo)的時(shí)候 SELECT 語(yǔ)句的查詢結(jié)果集就會(huì)送到游標(biāo)工作區(qū),為后面游標(biāo)的逐條讀取
結(jié)果集中的記錄做準(zhǔn)備。
3、使用游標(biāo)
語(yǔ)法格式:
FETCH 游標(biāo)名 INTO var_name [, var_name] ...
這句的作用是使用 游標(biāo)名
這個(gè)游標(biāo)來(lái)讀取當(dāng)前行,并且將數(shù)據(jù)保存到 var_name 這個(gè)變量中,游標(biāo)指針指到下一行。如果游標(biāo)讀取的數(shù)據(jù)行有多個(gè)列名,則在 INTO 關(guān)鍵字后面賦值給多個(gè)變量名即可。
注意: var_name必須在聲明游標(biāo)之前就定義好。
舉例:
FETCH emp_cur INTO emp_id, emp_sal ;
注意: 游標(biāo)的查詢結(jié)果集中的字段數(shù),必須跟 INTO 后面的變量數(shù)一致
4、關(guān)閉游標(biāo)
語(yǔ)法格式:
CLOSE 游標(biāo)名;
當(dāng)我們使用完游標(biāo)后需要關(guān)閉掉該游標(biāo)。因?yàn)橛螛?biāo)會(huì)占用系統(tǒng)資源
,如果不及時(shí)關(guān)閉,游標(biāo)會(huì)一直保持到存儲(chǔ)過程結(jié)束,影響系統(tǒng)運(yùn)行的效率。而關(guān)閉游標(biāo)的操作,會(huì)釋放游標(biāo)占用的系統(tǒng)資源。
關(guān)閉游標(biāo)之后,我們就不能再檢索查詢結(jié)果中的數(shù)據(jù)行,如果需要檢索只能再次打開游標(biāo)。
3、代碼舉例
#創(chuàng)建存儲(chǔ)過程“get_count_by_limit_total_salary()”, #聲明IN參數(shù) limit_total_salary,DOUBLE類型;聲明OUT參數(shù)total_count,INT類型。 #函數(shù)的功能可以實(shí)現(xiàn)累加薪資最高的幾個(gè)員工的薪資值, #直到薪資總和達(dá)到limit_total_salary參數(shù)的值,返回累加的人數(shù)給total_count。 DELIMITER $ CREATE PROCEDURE get_count_by_limit_total_salary(IN limit_total_salary DOUBLE,OUT total_count INT) BEGIN DECLARE count_emp INT DEFAULT 0; #用來(lái)記錄人數(shù),默認(rèn)值是0 DECLARE sum_sal DOUBLE DEFAULT 0; #記錄總薪資 DECLARE one_sal DOUBLE DEFAULT 0; #記錄一個(gè)人的薪資 #聲明游標(biāo),把查詢到的工資結(jié)果集從高到低排序 DECLARE emp_cur CURSOR FOR SELECT salary FROM employees ORDER BY salary DESC; OPEN emp_cur; #打開游標(biāo) #用循環(huán)語(yǔ)句遍歷,知道總薪資滿足題目要求 REPEAT #開始使用游標(biāo) FETCH emp_cur INTO one_sal; SET sum_sal = sum_sal + one_sal; SET count_emp = count_emp + 1; UNTIL sum_sal >= limit_total_salary END REPEAT; CLOSE emp_cur; #關(guān)閉游標(biāo) #把結(jié)果返回給total_count SELECT count_emp INTO total_count; END $ DELIMITER ; CALL get_count_by_limit_total_salary(30000,@count); SELECT @count;
思路分析: 先創(chuàng)建存儲(chǔ)過程,然后再根據(jù)實(shí)際情況declare自己需要的變量來(lái)滿足題目的要求,游標(biāo)要按步驟來(lái):創(chuàng)建游標(biāo)、打開游標(biāo)、使用游標(biāo)最后再關(guān)閉游標(biāo);其中要注意使用游標(biāo)在循環(huán)中,可以提高代碼的簡(jiǎn)潔度。
4、小結(jié)
游標(biāo)是 MySQL 的一個(gè)重要的功能,為逐條讀取
結(jié)果集中的數(shù)據(jù),提供了完美的解決方案。跟在應(yīng)用層面實(shí)現(xiàn)相同的功能相比,游標(biāo)可以在存儲(chǔ)程序中使用,效率高,程序也更加簡(jiǎn)潔。
但同時(shí)也會(huì)帶來(lái)一些性能問題,比如在使用游標(biāo)的過程中,會(huì)對(duì)數(shù)據(jù)行進(jìn)行加鎖
,這樣在業(yè)務(wù)并發(fā)量大的時(shí)候,不僅會(huì)影響業(yè)務(wù)之間的效率,還會(huì)消耗系統(tǒng)資源
,造成內(nèi)存不足,這是因?yàn)橛螛?biāo)是在內(nèi)存中進(jìn)行的處理。
建議: 養(yǎng)成用完之后就關(guān)閉的習(xí)慣,這樣才能提高系統(tǒng)的整體效率。
愛在結(jié)尾:游標(biāo)的使用結(jié)合了以前學(xué)習(xí)過的存儲(chǔ)過程、流程控制以及用戶自定義變量相關(guān)的知識(shí)點(diǎn),單單看游標(biāo)這一個(gè)知識(shí)點(diǎn)是不難的,自己還是應(yīng)該多多回顧以前學(xué)過的知識(shí)點(diǎn),做到融會(huì)貫通。
到此這篇關(guān)于MySQL游標(biāo)詳細(xì)介紹的文章就介紹到這了,更多相關(guān)MySQL游標(biāo)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法
這篇文章主要介紹了MySQL從命令行導(dǎo)入SQL腳本時(shí)出現(xiàn)中文亂碼的解決方法,分析了中文亂碼出現(xiàn)的原因并給出了兩種解決方法供大家參考,需要的朋友可以參考下2016-09-09mysql unique option prefix myisam_recover instead of myisam-
Using unique option prefix myisam_recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead2016-05-05MySQL出現(xiàn)SQL Error (2013)連接錯(cuò)誤的解決方法
這篇文章主要介紹了MySQL出現(xiàn)SQL Error (2013)連接錯(cuò)誤的解決方法,2013錯(cuò)誤主要還是在于用戶的授權(quán)問題,需要的朋友可以參考下2016-06-06MySQL全文索引、聯(lián)合索引、like查詢、json查詢速度哪個(gè)快
這篇文章主要介紹了MySQL全文索引、聯(lián)合索引、like查詢、json查詢速度大比拼,通過實(shí)例代碼截圖的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02MySQL中distinct語(yǔ)句去查詢重復(fù)記錄及相關(guān)的性能討論
這篇文章主要介紹了MySQL中distinct語(yǔ)句去查詢重復(fù)記錄及相關(guān)的性能討論,文中的觀點(diǎn)是在一定情況下避免在最高層查詢中使用distinct,需要的朋友可以參考下2016-01-01mysql數(shù)據(jù)庫(kù)中的information_schema和mysql可以刪除嗎?
這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)中的information_schema和mysql可以刪除嗎這個(gè)問題,需要的朋友可以參考下2014-05-05關(guān)于MySQL外鍵的簡(jiǎn)單學(xué)習(xí)教程
這篇文章主要介紹了關(guān)于MySQL外鍵的簡(jiǎn)單學(xué)習(xí)教程,對(duì)InnoDB引擎下的外鍵約束做了簡(jiǎn)潔的講解,需要的朋友可以參考下2015-11-11當(dāng)面試官問mysql中char與varchar的區(qū)別
這篇文章主要以聊天形式圖片的添加,將面試官面試真實(shí)場(chǎng)景體現(xiàn)出來(lái),好奇的朋友不要錯(cuò)過奧2021-08-08