存儲過程之游標插入數據


前言:新項目需要添加 刪除用戶在系統內的所有痕跡、新增排行榜及獲取用戶的排名 兩個功能

因為排行榜模塊相對而言比較有代表性,故此處僅使用排行榜模塊,

游標的定義

用於臨時存儲一個查詢返回的多行數據(結果集,類似於java的jdbc連接返回的ResultSet集合),通過遍歷游標,可以逐行訪問處理該結果集的數據.

游標的使用方式:  聲明---打開--讀取---關閉

游標的語法

游標聲明:

CURSOR 游標名(參數列表)  IS 查詢語句;

游標的打開:

OPEN 游標名

游標的取值:

FETCH 游標名 INTO 變量列表

游標的關閉:

CLOSE 游標名

游標的屬性

 

游標的屬性 返回值類型 說明
%ROWCOUNT 整型 獲取FETCH語句返回的數據行數
%FOUND 布爾型 最近的FETCH語句返回一行數據則為真,否則為加
%NOTFOUND 布爾型 與%FOUND屬性返回值相反
%ISOPEN 布爾型 游標已經打開時值為真,否則為假

以上內容摘抄自:https://www.cnblogs.com/tanlei-sxs/p/9807982.html

首先,寫一個存儲過程的基礎語法(參考上一篇文章):https://www.cnblogs.com/fuhui-study-footprint/p/11975812.html

之后將游標的語法搬過來融合

-- 插入科目一數據
drop procedure p_ranking_subject1;
CREATE PROCEDURE `p_ranking_subject1`()
begin
     -- 聲明接收游標返回的變量
	DECLARE user_id1 INT;
	DECLARE score1 INT;
	DECLARE test_type1 INT;
	DECLARE test_time1 INT;
	-- 聲明排名變量
	DECLARE ranking_no int DEFAULT 0;
     -- 聲明游標是否是最后一頁變量
	DECLARE done int DEFAULT 0;
	

     -- 此處聲明游標,獲取排名的信息,將結果集,放入ranking游標
	DECLARE ranking CURSOR FOR select user_id,score,test_type,test_time from t_user_test where test_type = 1 group by user_id order by score desc, test_time asc, create_time asc;
     -- 若沒有數據返回,程序繼續,並將變量IS_FOUND設為0 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
     -- 此處執行一次,排名+1,因為查詢語句已經是根據排名查詢出來的,所以按照順序設置排名就可以了 set ranking_no = ranking_no + 1; -- 打開游標 open ranking; -- 將游標中的值賦值給變量,注意:變量名不要和返回的列名同名,變量順序要和sql結果列的順序一致 fetch ranking into user_id1, score1, test_type1, test_time1; -- 當s不等於1,也就是未遍歷完時,會一直循環 while done <> 1 do -- 執行業務邏輯 insert into t_ranking(`no`,`user_id`,`score`,`test_type`,`test_time`, `create_time`) values (ranking_no, user_id1, score1, test_type1, test_time1, now()); set ranking_no = ranking_no + 1; fetch ranking into user_id1, score1, test_type1, test_time1; -- 當s等於1時表明遍歷以完成,退出循環 end while; -- 關閉游標 close ranking; end;
-- 執行存儲過程 call p_ranking_subject1();

 上面存儲過程是我的邏輯,很low勉強算是達到目的,如果有大神看出有更好的方法,非常期望您能給予指點!

在寫這篇文章的時候,又看了幾篇文章,其中有雙游標的使用,例:

CREATE PROCEDURE procedureDemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
 -- 聲明光標接收游標 DECLARE a CHAR(16); DECLARE b, c INT;

-- 聲明游標 DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 打開游標 OPEN cur1; OPEN cur2;
-- 遍歷游標 read_loop: LOOP
-- 將游標的值取出 FETCH cur1 INTO a, b; FETCH cur2 INTO c;

   -- 判斷循環是否結束 IF done THEN LEAVE read_loop; END IF;

   -- 邏輯 IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END LOOP; CLOSE cur1; CLOSE cur2; END;

其中大部分文章對游標的循環用的都是loop,loop也是mysql循環的一種方式,具體參考:https://www.cnblogs.com/Luouy/p/7301360.html?utm_source=itdadao&utm_medium=referral


免責聲明!

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



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