Description\n-----------\n\nA cursor is a structure that allows you to go over records sequentially, and perform processing based on the result.\n\nMariaDB permits cursors inside stored programs, and MariaDB cursors are non-scrollable, read-only and case-insensitive.\n\n Non-scrollable means that the rows can only be fetched in the order specified by the SELECT statement. Rows cannot be skipped, you cannot jump to a specific row, and you cannot fetch rows in reverse order.\n Read-only means that data cannot be updated through the cursor.\n Assensitive means that the cursor points to the actual underlying data. This kind of cursor is quicker than the alternative, an insensitive cursor, as no data is copied to a temporary table. However, changes to the data being used by the cursor will affect the cursor data.\n\nCursors are created with a DECLARE CURSOR statement and opened with an OPEN statement. Rows are read with a FETCH statement before the cursor is finally closed with a CLOSE statement.\n\nWhen FETCH is issued and there are no more rows to extract, the following error is produced:\n\n``sql\nERROR 1329 (02000): No data - zero rows fetched, selected, or processed\n`\n\nTo avoid problems, a DECLARE HANDLER statement is generally used. The HANDLER should handler the 1329 error, or the '02000' SQLSTATE, or the NOT FOUND error class.\n\nCursors can be declared for a prepared statement name, enabling full support for Dynamic SQL within stored routines. The SQL Standard syntax for  <dynamic declare cursor> is supported: a cursor is declared with the FOR clause to bind it to a prepared statement name, which is then prepared and opened normally. Cursors may also still SELECT from views, which can be created dynamically via prepared statements.&#x20;\n\nOnly SELECT statements are allowed for cursors, and they cannot be contained in a variable - so, they cannot be composed dynamically. However, it is possible to SELECT from a view. Since the CREATE VIEW statement can be executed as a prepared statement, it is possible to dynamically create the view that is queried by the cursor.&#x20;\n\nCursors can have parameters. Cursor parameters can appear in any part of the DECLARE CURSOR select_statement where a stored procedure variable is allowed (select list, WHERE, HAVING, LIMIT` etc). See DECLARE CURSOR and OPEN for syntax, and below for an example.\n\nCursors cannot have parameters.\n\nExamples\n--------\n\nCREATE TABLE c1(i INT);\n\nCREATE TABLE c2(i INT);\n\nCREATE TABLE c3(i INT);\n\nDELIMITER //\n\nCREATE PROCEDURE p1()\nBEGIN\n  DECLARE done INT DEFAULT FALSE;\n  DECLARE x, y INT;\n  DECLARE cur1 CURSOR FOR SELECT i FROM test.c1;\n  DECLARE cur2 CURSOR FOR SELECT i FROM test.c2;\n  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;\n\n  OPEN cur1;\n  OPEN cur2;\n\n  read_loop: LOOP\n    FETCH cur1 INTO x;\n    FETCH cur2 INTO y;\n    IF done THEN\n      LEAVE read_loop;\n    END IF;\n    IF x < y THEN\n      INSERT INTO test.c3 VALUES (x);\n    ELSE\n      INSERT INTO test.c3 VALUES (y);\n    END IF;\n  END LOOP;\n\n  CLOSE cur1;\n  CLOSE cur2;\nEND; //\n\nDELIMITER ;\n\nINSERT INTO c1 VALUES(5),(50),(500);\n\nINSERT INTO c2 VALUES(10),(20),(30);\n\nCALL p1;\n\nSELECT  FROM c3;\n\nURL: https://mariadb.com/docs/server/reference/sql-statements/programmatic-compound-statements/programmatic-compound-statements-cursors/cursor-overview