Use cursor

1. Cursor

Sometimes, it is necessary to move forward or backward one or more rows in the retrieved rows. This is the reason for using cursors. The cursor is a database query stored on the MySQL server. It is not a select statement, but a result set retrieved by the statement. After storing the cursor, the application can scroll or browse the data as needed.

Cursors are mainly used in interactive applications, where users need to scroll through the data on the screen and browse or make changes to the data.
MySQL cursors can only be used in stored procedures (and functions).


2. Use the cursor

The main steps to use a cursor are:

  • Before a cursor can be used, it must be declared (defined). This process does not actually retrieve data, it just defines the select statement to be used.
  • Once declared, the cursor must be opened for use. This process uses the previously defined select statement to actually retrieve the data.
  • For the cursor filled with data, fetch (retrieve) each row as needed.
  • At the end of the use of the cursor, the cursor must be closed.

After declaring the cursor, you can open and close the cursor as often as necessary. After the cursor is opened, the fetch operation can be performed frequently as needed.

2.1 Create a cursor

The cursor is created with the declare statement. Declare names the cursor and defines the corresponding select statement, with where and other clauses as needed.

Insert picture description here

The declare statement is used to define and name the cursor, here is ordernumbers. After the stored procedure is processed, the cursor disappears (because it is limited to the stored procedure).

After defining the cursor, you can open it.


2.2 Open and close the cursor

The cursor is opened with the open cursor statement

Insert picture description here
The query is executed when the open statement is processed, and the retrieved data is stored for browsing and scrolling.

After the cursor processing is completed, the statement close cursor can be used to close the cursor:

Insert picture description here

close releases all internal memory and resources used by the cursor, so each cursor should be closed when it is no longer needed.

After a cursor is closed, if it is not reopened, it cannot be used. However, the declared cursor does not need to be declared again, just open it with the open statement.


2.3 Use cursor data

After a cursor is opened, you can use the fetch statement to access each row of it separately. fetch specifies what data to retrieve (the required columns) and where to store the retrieved data. It also moves the internal row pointer in the cursor forward so that the next fetch statement retrieves the next row (do not read the same row repeatedly).

Insert picture description here

fetch is used to retrieve the order_num column of the current row (will automatically start from the first row) into a locally declared variable named o. No processing is done on the retrieved data.

Insert picture description here
As in the previous example, this example uses fetch to retrieve the current order_num into the declared variable named o. But unlike the previous example, the fetch in this example is in the repeat, so it repeats until done is true (specified by until done end repeat;). To make it work, define the variable done with a default 0 (false, no end). So, how can done be set to true at the end? The answer is to use the following statement:

Insert picture description here

This statement defines a continue handler, which is the code that is executed when the condition occurs. Here, it indicates that when sqlstate '02000' appears, set done=1. sqlstate '02000' is a condition not found. This condition occurs when the repeat cannot continue because there are no more rows for the loop.

There is a specific order in which declare statements are issued. Local variables defined with the declare statement must be defined before any cursor or handle is defined, and the handle must be defined after the cursor.

If you call this stored procedure, it will define several variables and a continue handler, define and open a cursor, read all rows repeatedly, and then close the cursor.

If everything is normal, you can put whatever processing you need in the loop (after the fetch statement, before the loop ends).

Insert picture description hereInsert picture description here

In this example, we added another variable named t (to store the total of each order). This stored procedure also creates a new table (if it does not exist) while it is running, named ordertotals. This table will hold the results generated by the stored procedure. Fetch takes each order_num as before, and then executes another stored procedure with call to calculate the total tax with each order (the result is stored in t). Finally, use insert to save the order number and total of each order.

This stored procedure does not return data, but it can create and populate another table, which can be viewed with a simple select statement:

Insert picture description here


-- 定义名为ordernumbers的游标,使用了可以检索所有订单的SELECT语句
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN 
   DECLARE ordernumbers CURSOR
   FOR 
   SELECT order_num FROM orders;
END//

DELIMITER ;

-- 打开游标
OPEN ordernumbers;

-- 关闭游标
CLOSE ordernumbers;

-- 删除存储过程,再建立一个
DROP PROCEDURE processorders;

-- 从游标中检索单个行(第一行)
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN

   -- declare local variables 
   DECLARE o INT;
   
   -- declare the cursor
   DECLARE ordernumbers CURSOR
   FOR 
   SELECT order_num FROM orders;
   
   -- open the cursor
   OPEN ordernumbers;
   
   -- get order number
   FETCH ordernumbers INTO o; 
   
   -- close the cursor
   CLOSE ordernumbers;
   
END//

DELIMITER ;

-- 删除存储过程,再建立一个
DROP PROCEDURE processorders;


-- 循环检索数据,从第一行到最后一行
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN

   -- declare local variables
   DECLARE done BOOLEAN DEFAULT 0;
   DECLARE o INT;
   
   -- declare the cursor 
   DECLARE ordernumbers CURSOR
   FOR 
   SELECT order_num FROM orders;
   
   -- declare continue handler
   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
   
   -- open the cursor
   OPEN ordernumbers;
   
   -- loop through all rows
   REPEAT
   
     -- get order number
     FETCH  ordernumbers INTO o;
     
   -- end of loop 
   UNTIL done END REPEAT;
   
   -- close the cursor
   CLOSE ordernumbers;
   
END//

DELIMITER ;

-- 删除存储过程,再建立一个
DROP PROCEDURE processorders;

-- 存储过程、游标、逐行处理以及存储过程调用其他存储过程的一个完整的工作样例
DELIMITER //
CREATE PROCEDURE processorders()
BEGIN

   -- declare local variables
   DECLARE done BOOLEAN DEFAULT 0;
   DECLARE o INT;
   DECLARE t DECIMAL(8,2);
   
   -- declare the cursor
   DECLARE ordernumbers CURSOR
   FOR 
   SELECT order_num FROM orders;
   
   -- declare continue handler
   DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
   
   -- create a table to store the results
   CREATE TABLE IF NOT EXISTS ordertotals
     (order_num INT, total DECIMAL(8,2));
     
   -- open the cursor
   OPEN ordernumbers;
   
   -- loop through all rows
   REPEAT
   
      -- get order number
      FETCH ordernumbers INTO o;
      
      -- get the total for this order
      CALL ordertotal(o,1,t);
      
      -- insert order and total into ordertotals
      INSERT INTO ordertotals(order_num, total)
      VALUES(o,t);
      
      -- end of loop 
      UNTIL done END REPEAT;
      
      -- close the cursor
      CLOSE ordernumbers;
      
END//

DELIMITER ;

-- 用select语句查看表
SELECT * FROM ordertotals;

Guess you like

Origin blog.csdn.net/weixin_49984044/article/details/108828317