MySQL 游標的使用


MySQL 游標

游標的特性

  • 不敏感:數據庫可以選擇不復制結果集

  • 只讀

  • 不滾動:游標只能向一方向前進,並且不可以跳過任何一行數據

游標的優點

  • 游標是針對行操作的,對從數據庫中 select 查詢得到的結果集的 每一行可以

    進行分開的獨立的相同或者不相同的操作,是一種分離的思想。

游標的缺點

  • 性能不高

  • 只能一行一行操作

  • 使用游標會產生死鎖,造成內存開銷大

游標的適用場景

  • 存儲過程

  • 函數

  • 觸發器

  • 事件

游標的操作

1、游標的定義

DECLARE 光標名稱 CURSOR FOR 查詢語法

declare cursor_name cursor for select_statement

2、打開游標

OPEN 光標名稱

open cursor_name

3、取游標中的數據

FETCH 光標名稱 INFO var_name [,var_name ].....

fetch cursor_name info var_name

4、關閉游標

CLOSE curso_name;

close 光標名稱

5、釋放游標

DEALLOCATE 光標名稱

deallocate cursor_name;

游標示例
create table student(
    stuId int primary key auto_increment,
    stuName varchar(20),
    stuSex varchar(2),
    stuAge int
)default charset=utf8;
​
insert into student(stuName,stuSex,stuAge) values
('小明','男',20),
('小花','女',19),
('大赤','男',20),
('可樂','男',19),
('瑩瑩','女',19);

普通案例

delimiter //
create procedure p1()
begin
    declare id int;
    declare name varchar(100) character set utf8;
    declare done int default 0;
    -- 聲明游標
    declare mc cursor for select stuId,stuName from student where stuAge >19;
    declare continue handler for not found set done = 1;
    -- 打開游標
    open mc;
    -- 獲取結果
    fetch mc into id,name;
    -- 這里是為了顯示獲取結果
    select id,name;
    -- 關閉游標
    close mc;
end //
delimiter ;

試使用 三種方式 使用游標創建一個存儲過程,統計年齡大於19的記錄的數量

Loop循環
-- 定義語法結束符號
delimiter //
-- 創建一個 名稱為 p2 的存儲過程
create procedure p2()
begin
    -- 創建 用於接收游標值的變量
    declare id,age,total int;
    -- 注意 接收游標值為中文時 需要 給變量 指定 字符集為utf8
    declare name,sex varchar(20) character set utf8;
    
    -- 游標結束的標志
    declare done int default 0;
    -- 聲明游標
    declare cur cursor for select stuId,stuName,stuSex,stuAge from student where stuAge > 19;
    -- 指定游標循環結束時的返回值 
    declare continue handler for not found set done =1;
    -- 打開游標
    open cur;
    
    -- 初始化 變量
    set total = 0;
    
    -- loop 循環
    xxx:loop
        -- 根據游標當前指向的一條數據  
        fetch cur into id,name,sex,age;
        -- 當 游標的返回值為 1 時 退出 loop循環 
        if done = 1 then
            leave xxx;
        end if;
        -- 累計
        set total = total + 1;
    end loop;
    -- 關閉游標
    close cur;
    -- 輸出 累計的結果
    select total;
end //
delimiter ;
while 循delimiter /-- 創建一個 名稱為 p3 的存儲過程create procedure p3()
delimiter //
-- 創建一個 名稱為 p3 的存儲過程
create procedure p3()
begin
    -- 創建 用於接收游標值的變量
    declare id,age,total int;
    -- 注意 接收游標值為中文時 需要 給變量 指定 字符集為utf8
    declare name,sex varchar(20) character set utf8;
    -- 游標結束的標志
    declare done int default 0;
    -- 聲明游標
    declare cur cursor for select stuId,stuName,stuSex,stuAge from student where stuAge > 19;
    -- 指定游標循環結束時的返回值 
    declare continue handler for not found set done = 1;
    -- 打開游標
    open cur;
    
    -- 初始化 變量
    set total = 0;
    
    -- while 循環
    while done != 1 do
        fetch cur into id,name,sex,age;
          if done != 1 then
             set total = total + 1;
          end if;    
    end while;
    -- 關閉游標
    close cur;
    -- 輸出 累計的結果
    select total;
end //
delimiter ;
repeat 循環
delimiter //
-- 創建一個 名稱為 p3 的存儲過程
create procedure p3()
begin
    -- 創建 用於接收游標值的變量
    declare id,age,total int;
    -- 注意 接收游標值為中文時 需要 給變量 指定 字符集為utf8
    declare name,sex varchar(20) character set utf8;
    -- 游標結束的標志
    declare done int default 0;
    -- 聲明游標
    declare cur cursor for select stuId,stuName,stuSex,stuAge from student where stuAge > 19;
    -- 指定游標循環結束時的返回值 
    declare continue handler for not found set done = 1;
    -- 打開游標
    open cur;
    
    -- 初始化 變量
    set total = 0;
    
    -- repeat 循環
    repeat
        fetch cur into id,name,sex,age;
           if done != 1 then
              set total = total + 1;
           end if;
        until done = 1
    end repeat;
    -- 關閉游標
    close cur;
    -- 輸出 累計的結果
    select total;
end //
delimiter ;

 

 while 循環 repeat 循環 不知道 是不是理解錯了 會多循環一次…(還是游標多走了一次…)  ---->    進行累加計算時,先判斷游標的結束標志(done) 是否是為1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM