Mysql游标循环遍历
在大型的數(shù)據(jù)面前修改表內(nèi)的內(nèi)容,使用Mysql的游標(biāo)實現(xiàn)?
?
牧牛遛馬根據(jù)在存儲過程的接觸上實際的使用過程在代碼的每個邏輯后面加上注釋來大致實現(xiàn)一下遍歷數(shù)據(jù)表的邏輯
牧牛遛馬?
踩過的雷區(qū):
1、記不得游標(biāo)的查詢單詞————–fetch
2、設(shè)置循環(huán)條件的代碼寫錯————?
declare continue handler for not found set flag = false;?
漏寫for,handler錯寫成handle
3、游標(biāo)查詢的時候要賦值給多個變量,加逗號就可以了 (最后面一定要有分號)
fetch liuma into lmage,lmname;?
不能理解liuma里面有多條字段信息數(shù)據(jù)錯誤。
4、until 語句后面不能加分號?
正確———–until flag = false?
錯誤———–until flag = false;
5、變量在游標(biāo)或者h(yuǎn)andler的后面定義報錯:?
ERROR 1337 (42000): Variable or condition declaration after cursor or handler de?
claration
Surfing the code…
提個需求:?
更改表中的所有數(shù)據(jù),規(guī)則如下?
{?
如果年齡大于18,名字后面加上說自己是成年人;?
如果年齡小于18,名字后面加上說自己是未成年人;?
}?
1、先來一張表?
這里便于演示,只顯示了七條數(shù)據(jù),根據(jù)實現(xiàn)的思想邏輯可以擴(kuò)展到百萬數(shù)據(jù)的更新。
2、寫一下游標(biāo)遍歷數(shù)據(jù)的代碼
mysql> delimiter $$ mysql> create procedure muniu ()-> begin-> declare lmage int(11);-> declare lmname varchar(50);-> declare flag int default true;#聲明一個開關(guān)變量flag用于循環(huán)結(jié)束判斷默 認(rèn)是true;-> declare liuma cursor for(select age,name from emp);#申明一個游標(biāo),名 字叫l(wèi)iuma,因為游標(biāo)指向的表內(nèi)有兩個字段,需要兩個變量存儲,所有得申明兩個變量;->-> declare continue handler for not found set flag = false;-> open liuma;#打開游標(biāo)->-> repeat-> fetch liuma into lmage,lmname;#把游標(biāo)的內(nèi)容賦值到變量中。-> if(lmage<18)-> then update emp set name = concat(lmname,"說我是未成年人,讀 書少") where age = lmage;-> elseif(lmage>18 or lmage = 18)-> then update emp set name = concat(lmname,"說我是成年人,不會 亂來") where age = lmage;-> end if;-> until flag = false-> end repeat;-> close liuma;#關(guān)閉游標(biāo)-> end$$ Query OK, 0 rows affected (0.00 sec)mysql> delimiter ; mysql> mysql> mysql> mysql> call muniu; Query OK, 0 rows affected (0.51 sec)mysql> select * from emp; +----+------------------------------+------+---------+ | id | name | age | dept_in | +----+------------------------------+------+---------+ | 1 | 李四說我是成年人,不會亂來 | 18 | 1 | | 2 | 李四說我是成年人,不會亂來 | 18 | 1 | | 3 | 王五說我是成年人,不會亂來 | 20 | 1 | | 4 | 趙六說我是成年人,不會亂來 | 21 | 2 | | 5 | 大錘說我是未成年人,讀書少 | 12 | 3 | | 6 | 大錘說我是未成年人,讀書少 | 12 | 3 | | 7 | 中申通說我是成年人,不會亂來 | 23 | 3 | +----+------------------------------+------+---------+ 7 rows in set (0.00 sec)- ?
從上面的代碼運(yùn)行中我們發(fā)現(xiàn),當(dāng)age重復(fù)的時候,他們的名字會出現(xiàn)錯誤,第一條應(yīng)該是張三說,可是運(yùn)行出來是李四說,第5條應(yīng)該是小強(qiáng)說,運(yùn)行出來是大錘說。?
這是因為我們在查詢的時候使用的是age字段,每次更新數(shù)據(jù)的時候會把a(bǔ)ge相同的一起更新,第二次把第一次覆蓋導(dǎo)致。?
要解決這個問題,需要在游標(biāo)中傳入一個主鍵參數(shù),然后根據(jù)主鍵做條件,根據(jù)age做判斷就可以解決。這里就先把數(shù)據(jù)更新為不重復(fù)數(shù)據(jù),模擬age為主鍵的情況進(jìn)行演示一下:
先更新一下數(shù)據(jù)
mysql> update emp set name = "張三" where id =1; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set age = 13 where id =1; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "李四" where id= 2; Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "王五" where id= 3; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "趙六" where id= 4; Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "小強(qiáng)" where id= 5; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "大錘" where id= 6; Query OK, 1 row affected (0.04 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set age=11 where id= 6; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> update emp set name = "中申通" where id= 7; Query OK, 1 row affected (0.11 sec) Rows matched: 1 Changed: 1 Warnings: 0mysql> select * from emp; +----+--------+------+---------+ | id | name | age | dept_in | +----+--------+------+---------+ | 1 | 張三 | 13 | 1 | | 2 | 李四 | 18 | 1 | | 3 | 王五 | 20 | 1 | | 4 | 趙六 | 21 | 2 | | 5 | 小強(qiáng) | 12 | 3 | | 6 | 大錘 | 11 | 3 | | 7 | 中申通 | 23 | 3 | +----+--------+------+---------+ 7 rows in set (0.00 sec)- 一下游標(biāo)過程存儲:
?
總結(jié)
以上是生活随笔為你收集整理的Mysql游标循环遍历的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lua 语言中的点、冒号与self
- 下一篇: Redis 持久化之RDB和AOF