1. 程式人生 > >mysql 儲存過程中使用多遊標

mysql 儲存過程中使用多遊標

mysql的儲存過程可以很方便使用遊標來實現一些功能,儲存過程的寫法大致如下:

先建立一張表,插入一些測試資料:

DROP TABLE IF EXISTS netingcn_proc_test;

CREATE TABLE `netingcn_proc_test` (
  `id` INTEGER(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(20),
  `password` VARCHAR(20),
  PRIMARY KEY (`id`)
)ENGINE=InnoDB;

insert into netingcn_proc_test(name, password) values
('procedure1', 'pass1'),
('procedure2', 'pass2'),
('procedure3', 'pass3'),
('procedure4', 'pass4');

下面就是一個簡單儲存過程的例子:

drop procedure IF EXISTS test_proc;
delimiter //
create procedure test_proc()
begin
	-- 宣告一個標誌done, 用來判斷遊標是否遍歷完成
	DECLARE done INT DEFAULT 0;

	-- 宣告一個變數,用來存放從遊標中提取的資料
	-- 特別注意這裡的名字不能與由遊標中使用的列明相同,否則得到的資料都是NULL
	DECLARE tname varchar(50) DEFAULT NULL;
	DECLARE tpass varchar(50) DEFAULT NULL;

	-- 宣告遊標對應的 SQL 語句
	DECLARE cur CURSOR FOR
		select name, password from netingcn_proc_test;

	-- 在遊標迴圈到最後會將 done 設定為 1
	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

	-- 執行查詢
	open cur;
	-- 遍歷遊標每一行
	REPEAT
		-- 把一行的資訊存放在對應的變數中
		FETCH cur INTO tname, tpass;
		if not done then
			-- 這裡就可以使用 tname, tpass 對應的資訊了
			select tname, tpass;
		end if;
 	UNTIL done END REPEAT;
	CLOSE cur;
end
//
delimiter ;

-- 執行儲存過程
call test_proc();

需要注意的是變數的宣告、遊標的宣告和HANDLER宣告的順序不能搞錯,必須是先宣告變數,再申明遊標,最後宣告HANDLER。上述儲存過程的例子中只使用了一個遊標,那麼如果要使用兩個或者更多遊標怎麼辦,其實很簡單,可以這麼說,一個怎麼用兩個就是怎麼用的。例子如下:

drop procedure IF EXISTS test_proc_1;
delimiter //
create procedure test_proc_1()
begin
	DECLARE done INT DEFAULT 0;
	DECLARE tid int(11) DEFAULT 0;
	DECLARE tname varchar(50) DEFAULT NULL;
	DECLARE tpass varchar(50) DEFAULT NULL;

	DECLARE cur_1 CURSOR FOR
		select name, password from netingcn_proc_test;

	DECLARE cur_2 CURSOR FOR
		select id, name from netingcn_proc_test;

	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

	open cur_1;
	REPEAT
		FETCH cur_1 INTO tname, tpass;
		if not done then
			select tname, tpass;
		end if;
 	UNTIL done END REPEAT;
	CLOSE cur_1;

	-- 注意這裡,一定要重置done的值為 0
	set done = 0;

	open cur_2;
	REPEAT
		FETCH cur_2 INTO tid, tname;
		if not done then
			select tid, tname;
		end if;
 	UNTIL done END REPEAT;
	CLOSE cur_2;
end
//
delimiter ;

call test_proc_1();

上述程式碼和第一個例子中基本一樣,就是多了一個遊標宣告和遍歷遊標。這裡需要注意的是,在遍歷第二個遊標前使用了set done = 0,因為當第一個遊標遍歷玩後其值被handler設定為1了,如果不用set把它設定為 0 ,那麼第二個遊標就不會遍歷了。當然好習慣是在每個開啟遊標的操作前都用該語句,確保遊標能真正遍歷。當然還可以使用begin語句塊巢狀的方式來處理多個遊標,例如:

drop procedure IF EXISTS test_proc_2;
delimiter //
create procedure test_proc_2()
begin
	DECLARE done INT DEFAULT 0;
	DECLARE tname varchar(50) DEFAULT NULL;
	DECLARE tpass varchar(50) DEFAULT NULL;

	DECLARE cur_1 CURSOR FOR
		select name, password from netingcn_proc_test;

	DECLARE cur_2 CURSOR FOR
		select id, name from netingcn_proc_test;

	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

	open cur_1;
	REPEAT
		FETCH cur_1 INTO tname, tpass;
		if not done then
			select tname, tpass;
		end if;
 	UNTIL done END REPEAT;
	CLOSE cur_1;

	begin
		DECLARE done INT DEFAULT 0;
		DECLARE tid int(11) DEFAULT 0;
		DECLARE tname varchar(50) DEFAULT NULL;

		DECLARE cur_2 CURSOR FOR
			select id, name from netingcn_proc_test;

		DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

		open cur_2;
		REPEAT
			FETCH cur_2 INTO tid, tname;
			if not done then
				select tid, tname;
			end if;
	 	UNTIL done END REPEAT;
		CLOSE cur_2;
	end;
end
//
delimiter ;

call test_proc_2();

相關推薦

mysql儲存過程使用遊標

使用者變數一般以@開頭,作用於全域性範圍 區域性變數需用 declare 定義格式為 declare 變數名 資料型別 [default value]; mysql 資料型別有 int ,float,date,varchar(length)等 宣告的順序必須是 先宣告變

mysql 儲存過程使用遊標

mysql的儲存過程可以很方便使用遊標來實現一些功能,儲存過程的寫法大致如下: 先建立一張表,插入一些測試資料: DROP TABLE IF EXISTS netingcn_proc_test; CREATE TABLE `netingcn_proc_test`

Mysql儲存過程使用遊標

mysql的儲存過程可以很方便使用遊標來實現一些功能,儲存過程的寫法大致如下: 先建立一張表,插入一些測試資料: DROP TABLE IF EXISTS netingcn_proc_test; CREATE TABLE `netingcn_proc_

Oracle儲存過程層巢狀遊標的用法

Oracle sql指令碼程式碼   CREATE OR REPLACE   PROCEDURE P_DELETE_QK (pId in NUMBER, deep in NUMBER) AS   -- pId = 分類ID  deep = 深度,層級   on

MySql儲存過程傳參和不傳參以及java呼叫程式碼

資料庫表結構 1.mysql不傳參寫儲存過程 create procedure product() -- product為儲存過程名稱 begin select * from book; end 呼叫此儲存過程為 CALL product

MySQL儲存過程的3種迴圈,儲存過程的基本語法,ORACLE與MYSQL儲存過程/函式的使用區別,退出儲存過程方法

  學無止境 部落格園   首頁   新隨筆   聯絡   訂閱  管理 隨筆-1968  評論-103  文章-4&

MySQL 儲存過程執行DDL

一、定期增加表分割槽 1、增加表分割槽例 CREATE DEFINER=`root`@`127.0.0.1` PROCEDURE `p_create_Partition`(IN databaseName VARCHAR(50),IN tableName VARCHAR(50))L_END:BEGIN&nb

sqlserver儲存過程利用遊標遍歷結果集簡單示例及查詢資料庫時間

本例項用的是sqlserver2005   在儲存過程中遍歷結果,和查詢資料庫中所有 儲存過程名稱 加以處理以文字形式輸出 原始碼: drop procedure findName create procedure findName--建立一個名為findName的儲存過

MySQL儲存過程declare和set定義變數的區別

  在儲存過程中常看到declare定義的變數和@set定義的變數。簡單的來說,declare定義的類似是區域性變數,@set定義的類似全域性變數。  1、declare定義的變數類似java類中的區域性變數,僅在類中生效。即只在儲存過程中的begin和end之間生效。  2

mysql儲存過程使用select count(*) into 變數名 from +表+ where條件的用法

select count(*) into v_count from dual where userid=2;此語句的意思就是根據where條件查詢dual表,得到的行數存入變數v_count中(給變數賦值) 只能在儲存過程中編寫這樣的語句?如果在mysql的sql語句中編寫

mysql儲存過程 declare 和 set 定義變數的區別

mysql儲存過程中,定義變數有兩種方式: 1.使用set或select直接賦值,變數名以 @ 開頭. 例如:set @var=1; 可以在一個會話的任何地方宣告,作用域是整個會話,稱為會話變數。 2.以 DECLARE 關鍵字宣告的變數,只能在儲存過程中使用,稱為儲存過

Mysql儲存過程字串分割

今在專案中碰到了要把字串分割,記錄下來,以後可能還用的到 首先想上我的儲存過程程式碼 DELIMITER $$ USE `bplate`$$ DROP PROCEDURE IF EXISTS `lp_plate_insertplateinfo`$$ CREATE DE

mysql 儲存過程limit

1、mysql的高版本(5.5),儲存過程中的limit可以使用變數,如下:select * from student limit iStart,iNum; 2、mysql的低版本(5.1),儲存過程中的limit不能使用變數,編譯報錯,如下:You have an error in your SQL sy

儲存過程遊標使用

儲存過程 1:遊標使用 第一步:遊標宣告: 注:標點符號使用半形 CURSOR C_EMP IS /*宣告顯式遊標*/ SELECT * FROM dc_check_todo; /*遊標聲明後跟SQL語句*/ C_ROW C_EMP%ROWTYPE; /*定義遊標變數,

MySQL儲存過程的三種迴圈方式

“明月別枝驚鵲,清風半夜鳴蟬” 最近儲存過程寫得多,迴圈多數用在遊標裡,在這裡總結幾種迴圈的方式 CREATE DEFINER=`root`@`localhost` PROCEDURE `NewProc`() BEGIN DECLARE sta

mysql儲存過程的三種迴圈

#loop drop procedure if exists p1_; create procedure p1_ ( in in_ int , out out_ varchar(3)) #varch

MySQL儲存過程的IN,OUT,INOUT型別 用法

MySQL儲存過程中有IN,OUT,INOUT型別 ----------------------------------- ## IN IN引數只用來向過程傳遞資訊,為預設值。 ## MySQL儲存過程"in"引數:跟C語言的函式引數的值傳遞類似,MySQL儲存過程內部

MySQL儲存過程的3種迴圈

    -> begin    -> declare i int default 0;    -> loop_label:loop    ->     if i=3 then    ->         set i=i+1;    ->         iterate lo

MYSQL儲存過程迴圈CURSOR(遊標)使用

遊標概述 概括來說,遊標是一種臨時的資料庫物件,即用來存放一個表中所有資訊或者表中的一部分資料資訊(副本)。遊標也可以用來指向資料的某一行,可以充當資料庫中的行指標。 最常見用途就是儲存查詢結果,便於後面使用,遊標中的結果集都是有select語句產生的(臨時的資料庫物件)。

MySql儲存過程limit傳參

最近做專案用到了MySql資料庫,感覺還是蠻好用的,但是有同事前幾天寫儲存過程的時候老調不通,我看了看後發現把limit語句後面帶的引數隨便改成一個數字就除錯通過了,不知道是MySql當初就這麼設計的還是一個bug。後來在網上找到一個方法可以通過傳引數的方法解決該問題: