Create a Cursor
First create a data table in MySql:
-
CREATE TABLE IF NOT EXISTS `store` (
-
`id` int(11) NOT NULL AUTO_INCREMENT,
-
`name` varchar(20) NOT NULL,
-
`count` int(11) NOT NULL DEFAULT '1',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7;
-
-
INSERT INTO `store` (`id`, `name`, `count`) VALUES
-
(1, 'android', 15),
-
(2, 'iphone', 14),
-
(3, 'iphone', 20),
-
(4, 'android', 5),
-
(5, 'android', 13),
-
(6, 'iphone', 13);
Now we're going to do a function with stored procedures, count the total stock of the iphone, and export the total to the console.
-
-
delimiter //
-
drop procedure if exists StatisticStore;
-
CREATE PROCEDURE StatisticStore()
-
BEGIN
-
-
declare c int;
-
declare n varchar(20);
-
-
declare total int default 0;
-
-
declare done int default false;
-
-
declare cur cursor for select name,count from store where name = 'iphone';
-
-
declare continue HANDLER for not found set done = true;
-
-
set total = 0;
-
-
open cur;
-
-
read_loop:loop
-
-
fetch cur into n,c;
-
-
if done then
-
leave read_loop;
-
end if;
-
-
set total = total + c;
-
-
end loop;
-
-
close cur;
-
-
-
select total;
-
END;
-
-
call StatisticStore();
fetch is to get the data row currently pointed to by the cursor and point the pointer to the next row. Continuing to execute when the cursor has pointed to the last row will cause a cursor overflow.
When using the loop loop cursor, he will not monitor whether to the last data, such as the following code, which will cause a dead loop;
-
read_loop:loop
-
fetch cur into n,c;
-
set total = total+c;
-
end loop;
In MySql, a predefined NOT FOUND error in MySQL is triggered when a cursor overflow occurs, so the following code is used above to specify an event that defines a continue when a non-foundation error is raised, and to specify that the value of the done variable is modified when the event occurs.
-
declare continue HANDLER for not found set done = true;
So the following code is added to the loop:
-
-
if done then
-
leave read_loop;
-
end if;
If the value of done is true, the loop ends. Continue to execute the following code.
Usage mode
There are three ways to use cursors:
The first is the implementation of the above, using loop loops.
The second way is to use the while loop as follows:
-
drop procedure if exists StatisticStore1;
-
CREATE PROCEDURE StatisticStore1()
-
BEGIN
-
declare c int;
-
declare n varchar(20);
-
declare total int default 0;
-
declare done int default false;
-
declare cur cursor for select name,count from store where name = 'iphone';
-
declare continue HANDLER for not found set done = true;
-
set total = 0;
-
open cur;
-
fetch cur into n,c;
-
while(not done) do
-
set total = total + c;
-
fetch cur into n,c;
-
end while;
-
-
close cur;
-
select total;
-
END;
-
-
call StatisticStore1();
The third way is to use repeat to execute:
-
drop procedure if exists StatisticStore2;
-
CREATE PROCEDURE StatisticStore2()
-
BEGIN
-
declare c int;
-
declare n varchar(20);
-
declare total int default 0;
-
declare done int default false;
-
declare cur cursor for select name,count from store where name = 'iphone';
-
declare continue HANDLER for not found set done = true;
-
set total = 0;
-
open cur;
-
repeat
-
fetch cur into n,c;
-
if not done then
-
set total = total + c;
-
end if;
-
until done end repeat;
-
close cur;
-
select total;
-
END;
-
-
call StatisticStore2();
Vernier nesting
In mysql, each start end block is a separate scope area. Since events with the same error in MySql can only be defined once, Duplicate handler declared in the same block will be prompted at compile time if multiple definitions are used.
-
drop procedure if exists StatisticStore3;
-
CREATE PROCEDURE StatisticStore3()
-
BEGIN
-
declare _n varchar(20);
-
declare done int default false;
-
declare cur cursor for select name from store group by name;
-
declare continue HANDLER for not found set done = true;
-
open cur;
-
read_loop:loop
-
fetch cur into _n;
-
if done then
-
leave read_loop;
-
end if;
-
begin
-
declare c int;
-
declare n varchar(20);
-
declare total int default 0;
-
declare done int default false;
-
declare cur cursor for select name,count from store where name = 'iphone';
-
declare continue HANDLER for not found set done = true;
-
set total = 0;
-
open cur;
-
iphone_loop:loop
-
fetch cur into n,c;
-
if done then
-
leave iphone_loop;
-
end if;
-
set total = total + c;
-
end loop;
-
close cur;
-
select _n,n,total;
-
end;
-
begin
-
declare c int;
-
declare n varchar(20);
-
declare total int default 0;
-
declare done int default false;
-
declare cur cursor for select name,count from store where name = 'android';
-
declare continue HANDLER for not found set done = true;
-
set total = 0;
-
open cur;
-
android_loop:loop
-
fetch cur into n,c;
-
if done then
-
leave android_loop;
-
end if;
-
set total = total + c;
-
end loop;
-
close cur;
-
select _n,n,total;
-
end;
-
begin
-
-
end;
-
end loop;
-
close cur;
-
END;
-
-
call StatisticStore3();
The above is to implement a nested loop, of course, this example is far-fetched. Just take a look.
dynamic SQL
Mysql supports dynamic SQL functions.
-
set @sqlStr='select * from table where condition1 = ?';
-
prepare s1 for @sqlStr;
-
-
execute s1 using @condition1;
-
-
deallocate prepare s1;
-