SET sql_mode=ORACLE; # # MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND # # # Cursor attributes outside of an SP context # SELECT c%ISOPEN; ERROR 42000: Undefined CURSOR: c SELECT c%FOUND; ERROR 42000: Undefined CURSOR: c SELECT c%NOTFOUND; ERROR 42000: Undefined CURSOR: c SELECT c%ROWCOUNT; ERROR 42000: Undefined CURSOR: c # # Undefinite cursor attributes # CREATE PROCEDURE p1 AS BEGIN SELECT c%ISOPEN; END; $$ ERROR 42000: Undefined CURSOR: c CREATE PROCEDURE p1 AS BEGIN SELECT c%ROWCOUNT; END; $$ ERROR 42000: Undefined CURSOR: c CREATE PROCEDURE p1 AS BEGIN SELECT c%FOUND; END; $$ ERROR 42000: Undefined CURSOR: c CREATE PROCEDURE p1 AS BEGIN SELECT c%NOTFOUND; END; $$ ERROR 42000: Undefined CURSOR: c # # Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT # CREATE PROCEDURE p1 AS CURSOR c IS SELECT 1 AS c FROM DUAL; BEGIN SELECT c%ROWCOUNT; END; $$ CALL p1; ERROR 24000: Cursor is not open DROP PROCEDURE p1; CREATE PROCEDURE p1 AS CURSOR c IS SELECT 1 AS c FROM DUAL; BEGIN SELECT c%FOUND; END; $$ CALL p1; ERROR 24000: Cursor is not open DROP PROCEDURE p1; CREATE PROCEDURE p1 AS CURSOR c IS SELECT 1 AS c FROM DUAL; BEGIN SELECT c%NOTFOUND; END; $$ CALL p1; ERROR 24000: Cursor is not open DROP PROCEDURE p1; # # Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT with INVALID_CURSOR exception # CREATE PROCEDURE p1 AS CURSOR c IS SELECT 1 AS c FROM DUAL; BEGIN SELECT c%ROWCOUNT; EXCEPTION WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg; END; $$ CALL p1; c%ROWCOUNT msg INVALID_CURSOR caught DROP PROCEDURE p1; CREATE PROCEDURE p1 AS CURSOR c IS SELECT 1 AS c FROM DUAL; BEGIN SELECT c%FOUND; EXCEPTION WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg; END; $$ CALL p1; c%FOUND msg INVALID_CURSOR caught DROP PROCEDURE p1; CREATE PROCEDURE p1 AS CURSOR c IS SELECT 1 AS c FROM DUAL; BEGIN SELECT c%NOTFOUND; EXCEPTION WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg; END; $$ CALL p1; c%NOTFOUND msg INVALID_CURSOR caught DROP PROCEDURE p1; # # print() # CREATE TABLE t1 (a INT); CREATE PROCEDURE p1 AS CURSOR c IS SELECT * FROM t1 ORDER BY a; BEGIN EXPLAIN EXTENDED SELECT c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; END; $$ CALL p1(); id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select "c"%ISOPEN AS "c%ISOPEN","c"%ROWCOUNT AS "c%ROWCOUNT","c"%FOUND AS "c%FOUND","c"%NOTFOUND AS "c%NOTFOUND" DROP PROCEDURE p1; DROP TABLE t1; # # Declared data type of the attributes # CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (10); CREATE PROCEDURE p1 AS CURSOR c IS SELECT * FROM t1 ORDER BY a; BEGIN OPEN c; CREATE TABLE t2 AS SELECT c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; SHOW CREATE TABLE t2; DROP TABLE t2; CLOSE c; END; $$ CALL p1(); Table Create Table t2 CREATE TABLE "t2" ( "c%ISOPEN" int(1) NOT NULL, "c%ROWCOUNT" bigint(21) NOT NULL, "c%FOUND" int(1) DEFAULT NULL, "c%NOTFOUND" int(1) DEFAULT NULL ) DROP PROCEDURE p1; DROP TABLE t1; # # Core functionality # CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (20); INSERT INTO t1 VALUES (30); CREATE PROCEDURE p1 AS a INT:=0; CURSOR c IS SELECT * FROM t1 ORDER BY a; BEGIN SELECT a, c%ISOPEN; OPEN c; /* After OPEN and before FETCH: - %ROWCOUNT returns 0 - %FOUND and %NOTFOUND return NULL */ SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; FETCH c INTO a; SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; FETCH c INTO a; SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; FETCH c INTO a; SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; FETCH c INTO a; SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; CLOSE c; SELECT a, c%ISOPEN; /* After reopen and before FETCH: - %ROWCOUNT returns 0 - %FOUND and %NOTFOUND return NULL */ OPEN c; SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; FETCH c INTO a; SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND; CLOSE c; END; $$ CALL p1(); a c%ISOPEN 0 0 a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 0 1 0 NULL NULL a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 10 1 1 1 0 a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 20 1 2 1 0 a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 30 1 3 1 0 a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 30 1 3 0 1 a c%ISOPEN 30 0 a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 30 1 0 NULL NULL a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND 10 1 1 1 0 DROP PROCEDURE p1; DROP TABLE t1; # # %NOTFOUND as a loop exit condition # CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (20); INSERT INTO t1 VALUES (30); CREATE PROCEDURE p1 AS a INT:=0; CURSOR c IS SELECT * FROM t1 ORDER BY a; BEGIN OPEN c; LOOP FETCH c INTO a; EXIT WHEN c%NOTFOUND; SELECT a; END LOOP; CLOSE c; END; $$ CALL p1(); a 10 a 20 a 30 DROP PROCEDURE p1; DROP TABLE t1; # # %FOUND as a loop exit condition # CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (20); INSERT INTO t1 VALUES (30); CREATE PROCEDURE p1 AS a INT:=0; CURSOR c IS SELECT * FROM t1 ORDER BY a; BEGIN OPEN c; LOOP FETCH c INTO a; EXIT WHEN NOT c%FOUND; SELECT a; END LOOP; CLOSE c; END; $$ CALL p1(); a 10 a 20 a 30 DROP PROCEDURE p1; DROP TABLE t1;