Documentation Home
MySQL 8.0 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 46.8Mb
PDF (A4) - 46.9Mb
PDF (RPM) - 42.2Mb
HTML Download (TGZ) - 10.8Mb
HTML Download (Zip) - 10.8Mb
HTML Download (RPM) - 9.3Mb
Man Pages (TGZ) - 226.1Kb
Man Pages (Zip) - 331.6Kb
Info (Gzip) - 4.2Mb
Info (Zip) - 4.2Mb
Excerpts from this Manual

13.6.6 Cursors

MySQL supports cursors inside stored programs. The syntax is as in embedded SQL. Cursors have these properties:

  • Asensitive: The server may or may not make a copy of its result table

  • Read only: Not updatable

  • Nonscrollable: Can be traversed only in one direction and cannot skip rows

Cursor declarations must appear before handler declarations and after variable and condition declarations.

Example:

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;

User Comments
User comments in this section are, as the name implies, provided by MySQL users. The MySQL documentation team is not responsible for, nor do they endorse, any of the information provided here.
  Posted by James Rajkumar on September 19, 2018
In response to David Bergan
(Posted by David Bergan on February 23, 2012)

The Example which given by MySQL is correct.

IF we use your method by adding

read_loop: LOOP
-- This is the line that fixes the problem
SET done = FALSE ; # set done= FALSE

FETCH cur1 INTO a, b; # but this will be executed and it again set backs to TRUE
FETCH cur2 INTO c;

To make it right it should be as below

read_loop: LOOP

FETCH cur1 INTO a, b;
-- This is the line that fixes the problem
SET done = FALSE ; # Perfect from your example, but it's not needed.
FETCH cur2 INTO c;

[-- This is the kind of line that would cause the problem.
-- SELECT INTO returns 0 records
SELECT id INTO a FROM test.t1 WHERE 1 = 2 ; ]

By considering your point and the values will be
like a,b has 0 records which will be null for both a and b.
c has some not null value.

then the result will be an empty row inserted in the table t3 (which we don't want)

IF b < c THEN -- null < some value
INSERT INTO test.t3 VALUES (a,b); -- which will be (null,null) values inserted in the table t3.
ELSE
INSERT INTO test.t3 VALUES (a,c); -- obviously this condition will not be executed.
END IF;

By concluding that the original sample Example given by MySQL is correct.