MySQL usa cursores

Prefacio: MySQL5 o posterior admite la función del cursor

Por qué usar cursores: las operaciones de búsqueda de MySQL generalmente devuelven un conjunto de resultados, usando una simple instrucción SELECT, pero no hay forma de obtener la primera fila, la siguiente fila o una fila a la vez. A veces es necesario avanzar o retroceder una o más líneas entre las líneas recuperadas.

Introducción del cursor: un cursor es una consulta de base de datos almacenada en el servidor MySQL. No es una instrucción SELECT. Después de almacenar el cursor, la aplicación puede desplazarse o explorar los datos según sea necesario. Los cursores solo pueden usarse en procedimientos almacenados

Pasos para usar cursores:

  1. Antes de usar un cursor, debe declararse. Este proceso no recupera datos, solo define la instrucción SELECT que se utilizará
  2. Una vez declarado, el cursor debe abrirse para su uso. Este proceso recupera los datos utilizando la instrucción SELECT previamente definida
  3. Para los cursores llenos de datos, saque las filas según sea necesario
  4. Al final del cursor, el cursor debe estar cerrado.

 

Primero, crea un cursor

   El cursor se crea con una instrucción DECLARE y se define la instrucción SELECT correspondiente.

   Por ejemplo, la siguiente instrucción define un cursor llamado ordernumbers y define la correspondiente instrucción SELECT. Luego debe usar la instrucción OPEN para abrir el cursor antes de poder usarla. Después de usar el cursor, debe usar CLOSE para cerrar el cursor y liberar todos los recursos internos y la memoria utilizada por el cursor, por lo que cuando cada cursor ya no se use, debería cerrarse. Por supuesto, cuando llegue a FIN, el cursor se cerrará automáticamente

CREATE PROCEDURE processorders()
BEGIN
    DECLARE ordernumbers CURSOR
		FOR
		SELECT order_num FROM orders;
		OPEN ordernumbers;
		CLOSE ordernumbers;
END;

 

Segundo, usa el cursor

En el primer ejemplo, se recupera una sola fila del cursor. FETCH se usa para recuperar la columna order_num de la fila actual (desde la primera fila) en una variable local llamada o, sin ningún procesamiento de los datos recuperados

CREATE PROCEDURE processorders()
BEGIN
   -- 定义一个int类型的局部变量
    DECLARE o int;
		-- 定义游标到SELECT语句
    DECLARE ordernumbers CURSOR
		FOR
		SELECT order_num FROM orders;
		
		-- 打开游标
		OPEN ordernumbers;
		
		FETCH ordernumbers INTO o;
		
		-- 关闭游标
		CLOSE ordernumbers;
END;

 

En el siguiente ejemplo, recupera iterativamente datos de la primera fila a la última fila. A diferencia de un ejemplo, el FETCH en este ejemplo está en REPETIR, por lo que se ejecuta repetidamente hasta que hecho sea verdadero y hecho se define como falso al principio, entonces, ¿cómo se puede hacer que lo hecho sea verdadero al final?

La respuesta es esta declaración: DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; Esta declaración define un CONTINUE HANDLER, que es el código que se ejecuta cuando ocurre la condición, e indica que cuando ocurre SQLSTATE '02000', SET done = 1, SQLSTATE '02000' es una condición no encontrada, esta condición ocurre cuando REPEAT no tiene más filas para recorrer

CREATE PROCEDURE processorders()
BEGIN
    -- 定义布尔变量,默认为0
    DECLARE done BOOLEAN DEFAULT O;
		
   -- 定义一个int类型的局部变量
    DECLARE o int;
		
		-- 定义游标到SELECT语句
    DECLARE ordernumbers CURSOR
		FOR
		SELECT order_num FROM orders;
		
		DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
		
		-- 打开游标
		OPEN ordernumbers;
		
        -- 开始循环,直到done为真
 		REPEAT
		   FETCH ordernumbers INTO o;
		UNTIL done END REPEAT;
		
		-- 关闭游标
		CLOSE ordernumbers;
END;

 

Sinteticemos el ejemplo anterior para implementar una función. Esta vez, realizaremos un procesamiento real en los datos recuperados.

CREATE PROCEDURE processorders()
BEGIN
    -- 定义布尔变量,默认为0
    DECLARE done BOOLEAN DEFAULT O;
		
   -- 定义两个局部变量
    DECLARE o int;
		DECLARE t DECIMAL(8,2);
		
		-- 定义游标到SELECT语句
    DECLARE ordernumbers CURSOR
		FOR
		SELECT order_num FROM orders;
		
		-- 它指出当SQLSTATE '02000'出现时(也就是REPEAT由于没有更多的行循环时),SET done = 1,
		DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
		
		-- 创建一张表
		CREATE TABLE IF NOT EXISTS ordertotals(order_num INT, total DECIMAL(8,2));
		
		-- 打开游标
		OPEN ordernumbers;
		
		-- 开始循环 直到done为真
		REPEAT
		  -- 将游标第一行内容放入局部变量o中
		   FETCH ordernumbers INTO o;
			 -- 调用名为ordertotal的存储过程
			 CALL ordertotal(o, 1, t);
			 INSERT INTO ordertotals(order_num,total) VALUES(o,t);
		UNTIL done END REPEAT;
		
		-- 关闭游标
		CLOSE ordernumbers;
END;
CREATE DEFINER=`root`@`localhost` PROCEDURE `ordertotal`(
	IN onumber int,
	IN taxable BOOLEAN,
	OUT ototal DECIMAL(8,2)
)
BEGIN
    -- 定义存储过程体的内部变量
		DECLARE total DECIMAL(8,2);
		DECLARE taxrate int DEFAULT 6;
		
		SELECT SUM(item_price * quantity)
		FROM orderitems
		WHERE order_num = onumber
		INTO total;
		
		-- 判断客户订单是否需要增加营业税
		IF taxable THEN
			SELECT total + (total * taxrate/100) INTO total;
		END IF;
		
		-- 将订单总价返回到ototal变量中
		SELECT total INTO ototal;
END

En el procedimiento almacenado de procesadores anterior, se crea una tabla de total de pedidos. El proceso de almacenamiento total de pedidos consiste en calcular el pedido total (incluido el impuesto comercial) y finalmente guardarlo en la tabla de total de pedidos. Este procedimiento almacenado debe llamarse con CALL para ejecutarse.

CALL processorders();

De esta manera, utilizamos procedimientos almacenados, cursores, procesamiento fila por fila y procedimientos almacenados para llamar a otro procedimiento almacenado para completar un ejemplo de trabajo completo.

156 artículos originales publicados · Me gustaron 34 · Visitas 150,000+

Supongo que te gusta

Origin blog.csdn.net/bbj12345678/article/details/105609810
Recomendado
Clasificación