Stored procedure cursor

example:

At present, there are three tables A, B and C. among them, A and B are one to many relationships, and B and C are one to many relationships. Now it is necessary to save the primary key of table A in B into C;
The general idea is to query out B and update table C with an update statement, but there are more than 2000 pieces of data in table B,
Do you want to implement more than 2000 times? Obviously, it's not realistic; finally, we find and write a stored procedure and update the C table through a loop,
However, the writing method in stored procedures is in the form of cursors.

[introduction]

A cursor is actually a mechanism that can extract one record at a time from a result set that contains multiple data records.

The cursor acts as a pointer.

Although the cursor can traverse all the rows in the result, it only points to one row at a time.

The function of the cursor is to traverse the records returned from the query database for corresponding operations.

[usage]

1. Declare a cursor: declare the cursor name CURSOR for table; (the table here can be any collection you query)
2. Open the defined cursor: the name of the open cursor;
3. Get the next row of data: FETCH cursor name into testrangeid, versioned;
IV. statements to be executed (add, delete, modify and check): it depends on the specific situation
5. Release cursor: name of CLOSE cursor;
Note: every sentence of mysql stored procedure must be followed by; at the end, the temporary fields used need to be declared before the cursor is defined.

[examples]

-  
BEGIN  
  
--Defining variables  
declare testrangeid BIGINT;  
declare versionid BIGINT;   
declare done int;  
--Create a cursor and store data  
declare cur_test CURSOR for   
   select id as testrangeid,version_id as versionid from tp_testrange;  
--After the contents in the cursor are executed, the done Set to 1  
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;   
--Open cursor  
open cur_test;  
--Execute loop  
  posLoop:LOOP  
--Determine whether to end the cycle  
        IF done=1 THEN    
      LEAVE posLoop;  
    END IF;   
--Take the value in the cursor  
    FETCH  cur_test into testrangeid,versionid;  
--Perform update operation  
    update tp_data_execute set version_id=versionid where testrange_id = testrangeid;  
  END LOOP posLoop;  
--Release cursor  
CLOSE cur_test;  
  
END  
-  

 

 

Example 2:

Now we need to do a function with stored procedures to count the total stock of iPhones and output the total to the console.

 

--stay windows When writing stored procedures in the system, use the declare To declare a variable, you need to add this keyword, otherwise an error will be reported.  
delimiter //  
drop procedure if exists StatisticStore;  
CREATE PROCEDURE StatisticStore()  
BEGIN  
    --Create variables to receive cursor data  
    declare c int;  
    declare n varchar(20);  
    --Create total variable  
    declare total int default 0;  
    --Create end flag variable  
    declare done int default false;  
    --Create cursor  
    declare cur cursor for select name,count from store where name = 'iphone';  
    --Specifies the return value at the end of the cursor loop  
    declare continue HANDLER for not found set done = true;  
    --Set initial value  
    set total = 0;  
    --Open cursor  
    open cur;  
    --Start looping data in cursor  
    read_loop:loop  
    --According to a piece of data that the cursor currently points to  
    fetch cur into n,c;  
    --Determine whether the cursor's loop ends  
    if done then  
        leave read_loop;    --Jump out of cursor loop  
    end if;  
    --When getting a piece of data, the count Value to accumulate. You can do whatever you want,  
    set total = total + c;  
    --End cursor loop  
    end loop;  
    --Close cursor  
    close cur;  
  
    --Output results  
    select total;  
END;  
--Call stored procedure  
call StatisticStore(); 

 

fetch is to get the data row that the cursor currently points to, and point the pointer to the next row. If the cursor has already pointed to the last row, continuing execution will cause cursor overflow.
When using loop loop cursors, they will not monitor whether the last data is reached. Writing like the following code will cause a dead loop;

read_loop:loop  
fetch cur into n,c;  
set total = total+c;  
end loop;  

In mysql, when a cursor overflows, a pre-defined not found error of MySQL will be raised. Therefore, the following code is used to specify that when a not found error is raised, a continue event is defined, and the value of the done variable is modified when the event occurs.

declare continue HANDLER for not found set done = true;  

So add the following code to the loop:

--Determine whether the cursor's loop ends  
if done then  
    leave read_loop; -- jump out of cursor loop  
end if;  

If the value of done is true, the loop ends. Continue with the following code

How to use

There are three ways to use cursors:
The first is the above implementation, using loop loop;
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:

 

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();

 

Cursor nesting

In mysql, each begin end block is an independent scope area. Because the event of the same error in MySQL can only be defined once, if there are multiple definitions, the duplicate handler declared in the sample block will be prompted during compilation.

 

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 the function of dynamic SQL

set @sqlStr='select * from table where condition1 = ?';  
prepare s1 for @sqlStr;  
--If there are multiple parameters separated by commas  
execute s1 using @condition1;  
--Release manually, or when the connection is closed, the server will recycle automatically  
deallocate prepare s1; 

Keywords: MySQL Stored Procedure SQL Database

Added by bobicles2 on Tue, 16 Jun 2020 10:41:40 +0300