mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-10597 Cursors with parameters
This commit is contained in:
@ -827,3 +827,63 @@ SELECT f1(3), f1(4), f1(5), f1(6) FROM DUAL;
|
||||
f1(3) f1(4) f1(5) f1(6)
|
||||
3 4 4 5
|
||||
DROP FUNCTION f1;
|
||||
#
|
||||
# Start of MDEV-10597 Cursors with parameters
|
||||
#
|
||||
CREATE PROCEDURE p1(arg_value_a VARCHAR, arg_value_b VARCHAR,
|
||||
arg_pattern_a VARCHAR, arg_pattern_b VARCHAR)
|
||||
AS
|
||||
v_a VARCHAR(10);
|
||||
v_b VARCHAR(20);
|
||||
CURSOR c (p_value_a VARCHAR,
|
||||
p_value_b VARCHAR,
|
||||
p_pattern_a VARCHAR,
|
||||
p_pattern_b VARCHAR,
|
||||
p_limit_a INT,
|
||||
p_limit_b INT,
|
||||
p_unused TEXT) IS
|
||||
(SELECT p_value_a, p_value_b FROM DUAL
|
||||
WHERE p_value_a LIKE p_pattern_a LIMIT p_limit_a)
|
||||
UNION
|
||||
(SELECT p_value_b, p_value_a FROM DUAL
|
||||
WHERE p_value_b LIKE p_pattern_b LIMIT p_limit_b);
|
||||
BEGIN
|
||||
OPEN c(arg_value_a, (SELECT arg_value_b),
|
||||
arg_pattern_a, arg_pattern_b, 100, 101, 'x');
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT v_a, v_b;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1('aaa','bbb','aaa','bbb');
|
||||
v_a v_b
|
||||
aaa bbb
|
||||
v_a v_b
|
||||
bbb aaa
|
||||
SHOW PROCEDURE CODE p1;
|
||||
Pos Instruction
|
||||
0 set v_a@4 NULL
|
||||
1 set v_b@5 NULL
|
||||
2 cpush c@0
|
||||
3 set p_value_a@6 arg_value_a@0
|
||||
4 set p_value_b@7 (select arg_value_b@1)
|
||||
5 set p_pattern_a@8 arg_pattern_a@2
|
||||
6 set p_pattern_b@9 arg_pattern_b@3
|
||||
7 set p_limit_a@10 100
|
||||
8 set p_limit_b@11 101
|
||||
9 set p_unused@12 'x'
|
||||
10 copen c@0
|
||||
11 cfetch c@0 v_a@4 v_b@5
|
||||
12 jump_if_not 14(0) "c"%NOTFOUND
|
||||
13 jump 16
|
||||
14 stmt 0 "SELECT v_a, v_b"
|
||||
15 jump 11
|
||||
16 cclose c@0
|
||||
17 cpop 1
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# End of MDEV-10597 Cursors with parameters
|
||||
#
|
||||
|
@ -289,3 +289,466 @@ a
|
||||
30
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND
|
||||
#
|
||||
#
|
||||
# MDEV-10597 Cursors with parameters
|
||||
#
|
||||
#
|
||||
# OPEN with a wrong number of parameters
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(10));
|
||||
CREATE PROCEDURE p1(a_a INT,a_b VARCHAR)
|
||||
AS
|
||||
v_a INT;
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_a INT, p_b VARCHAR) IS SELECT * FROM t1 WHERE a=p_a;
|
||||
BEGIN
|
||||
OPEN c(a_a);
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
DBMS_OUTPUT.PUT_LINE('Fetched a record a='||TO_CHAR(v_a)||' b='||v_b);
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
ERROR 42000: Incorrect parameter count to cursor 'c'
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Cursor parameters are not visible outside of the cursor
|
||||
#
|
||||
CREATE PROCEDURE p1(a_a INT)
|
||||
AS
|
||||
v_a INT;
|
||||
CURSOR c (p_a INT) IS SELECT a FROM t1 WHERE a=p_a;
|
||||
BEGIN
|
||||
OPEN c(a_a);
|
||||
p_a:=10;
|
||||
END;
|
||||
$$
|
||||
ERROR HY000: Unknown system variable 'p_a'
|
||||
CREATE PROCEDURE p1(a_a INT)
|
||||
AS
|
||||
v_a INT;
|
||||
CURSOR c (p_a INT) IS SELECT a FROM t1 WHERE a=p_a;
|
||||
BEGIN
|
||||
p_a:=10;
|
||||
OPEN c(a_a);
|
||||
END;
|
||||
$$
|
||||
ERROR HY000: Unknown system variable 'p_a'
|
||||
#
|
||||
# Cursor parameter shadowing a local variable
|
||||
#
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE PROCEDURE p1(a INT)
|
||||
AS
|
||||
v_a INT:=NULL;
|
||||
p_a INT:=NULL;
|
||||
CURSOR c (p_a VARCHAR2) IS SELECT a FROM t1 WHERE p_a IS NOT NULL;
|
||||
BEGIN
|
||||
OPEN c(a);
|
||||
FETCH c INTO v_a;
|
||||
IF c%NOTFOUND THEN
|
||||
BEGIN
|
||||
SELECT 'No records found' AS msg;
|
||||
RETURN;
|
||||
END;
|
||||
END IF;
|
||||
CLOSE c;
|
||||
SELECT 'Fetched a record a='||v_a AS msg;
|
||||
INSERT INTO t1 VALUES (v_a);
|
||||
END;
|
||||
$$
|
||||
CALL p1(1);
|
||||
msg
|
||||
Fetched a record a=1
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
1
|
||||
1
|
||||
CALL p1(NULL);
|
||||
msg
|
||||
No records found
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
1
|
||||
1
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Parameters in SELECT list
|
||||
#
|
||||
CREATE PROCEDURE p1(a_a INT, a_b VARCHAR)
|
||||
AS
|
||||
v_a INT;
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_a INT, p_b VARCHAR) IS SELECT p_a,p_b FROM DUAL;
|
||||
BEGIN
|
||||
FOR i IN 0..1
|
||||
LOOP
|
||||
OPEN c(a_a + i,a_b);
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT 'Fetched a record a=' || v_a || ' b=' || v_b AS msg;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END LOOP;
|
||||
END;
|
||||
$$
|
||||
CALL p1(1,'b1');
|
||||
msg
|
||||
Fetched a record a=1 b=b1
|
||||
msg
|
||||
Fetched a record a=2 b=b1
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Parameters in SELECT list + UNION
|
||||
#
|
||||
CREATE PROCEDURE p1(a_a INT, a_b VARCHAR)
|
||||
AS
|
||||
v_a INT;
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_a INT, p_b VARCHAR) IS
|
||||
SELECT p_a,p_b FROM DUAL
|
||||
UNION ALL
|
||||
SELECT p_a+1,p_b||'b' FROM DUAL;
|
||||
BEGIN
|
||||
OPEN c(a_a,a_b);
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT 'Fetched a record a=' || v_a || ' b=' || v_b AS msg;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1(1,'b1');
|
||||
msg
|
||||
Fetched a record a=1 b=b1
|
||||
msg
|
||||
Fetched a record a=2 b=b1b
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Parameters in SELECT list + type conversion + warnings
|
||||
#
|
||||
CREATE PROCEDURE p1(a_a VARCHAR)
|
||||
AS
|
||||
v_a INT;
|
||||
CURSOR c (p_a INT) IS SELECT p_a FROM DUAL;
|
||||
BEGIN
|
||||
OPEN c(a_a);
|
||||
LOOP
|
||||
FETCH c INTO v_a;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT 'Fetched a record a=' || v_a AS msg;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1('1b');
|
||||
msg
|
||||
Fetched a record a=1
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'p_a' at row 1
|
||||
CALL p1('b1');
|
||||
msg
|
||||
Fetched a record a=0
|
||||
Warnings:
|
||||
Warning 1366 Incorrect integer value: 'b1' for column 'p_a' at row 1
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# One parameter in SELECT list + subselect
|
||||
#
|
||||
CREATE PROCEDURE p1(a_a VARCHAR)
|
||||
AS
|
||||
v_a VARCHAR(10);
|
||||
CURSOR c (p_a VARCHAR) IS
|
||||
SELECT p_a FROM DUAL UNION SELECT REVERSE(p_a) FROM DUAL;
|
||||
BEGIN
|
||||
OPEN c((SELECT a_a));
|
||||
LOOP
|
||||
FETCH c INTO v_a;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT v_a;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1('ab');
|
||||
v_a
|
||||
ab
|
||||
v_a
|
||||
ba
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Two parameters in SELECT list + subselect
|
||||
#
|
||||
SET sql_mode=ORACLE;
|
||||
CREATE PROCEDURE p1()
|
||||
AS
|
||||
v_a VARCHAR(10);
|
||||
v_b VARCHAR(20);
|
||||
CURSOR c (p_a VARCHAR, p_b VARCHAR) IS
|
||||
SELECT p_a, p_b FROM DUAL
|
||||
UNION
|
||||
SELECT p_b, p_a FROM DUAL;
|
||||
BEGIN
|
||||
OPEN c((SELECT 'aaa'),(SELECT 'bbb'));
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT v_a, v_b;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1();
|
||||
v_a v_b
|
||||
aaa bbb
|
||||
v_a v_b
|
||||
bbb aaa
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Two parameters in SELECT list + two parameters in WHERE + subselects
|
||||
#
|
||||
SET sql_mode=ORACLE;
|
||||
CREATE PROCEDURE p1(a_a VARCHAR, a_b VARCHAR)
|
||||
AS
|
||||
v_a VARCHAR(10);
|
||||
v_b VARCHAR(20);
|
||||
CURSOR c (value_a VARCHAR, value_b VARCHAR,
|
||||
pattern_a VARCHAR, pattern_b VARCHAR) IS
|
||||
SELECT value_a, value_b FROM DUAL WHERE value_a LIKE pattern_a
|
||||
UNION
|
||||
SELECT value_b, value_a FROM DUAL WHERE value_b LIKE pattern_b;
|
||||
BEGIN
|
||||
OPEN c((SELECT 'aaa'),(SELECT 'bbb'),(SELECT a_a),(SELECT a_b));
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT v_a, v_b;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1('%','%');
|
||||
v_a v_b
|
||||
aaa bbb
|
||||
v_a v_b
|
||||
bbb aaa
|
||||
CALL p1('aaa','xxx');
|
||||
v_a v_b
|
||||
aaa bbb
|
||||
CALL p1('xxx','bbb');
|
||||
v_a v_b
|
||||
bbb aaa
|
||||
CALL p1('xxx','xxx');
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Parameters in SELECT list + stored function
|
||||
#
|
||||
CREATE FUNCTION f1 (a VARCHAR) RETURN VARCHAR
|
||||
AS
|
||||
BEGIN
|
||||
RETURN a || 'y';
|
||||
END;
|
||||
$$
|
||||
CREATE PROCEDURE p1(a_a VARCHAR)
|
||||
AS
|
||||
v_a VARCHAR(10);
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_sel_a VARCHAR, p_cmp_a VARCHAR) IS
|
||||
SELECT p_sel_a, p_cmp_a FROM DUAL;
|
||||
BEGIN
|
||||
OPEN c(f1(a_a), f1(a_a));
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT v_a;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1('x');
|
||||
v_a
|
||||
xy
|
||||
CALL p1(f1(COALESCE(NULL, f1('x'))));
|
||||
v_a
|
||||
xyyy
|
||||
DROP PROCEDURE p1;
|
||||
DROP FUNCTION f1;
|
||||
#
|
||||
# One parameter in WHERE clause
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(10));
|
||||
CREATE TABLE t2 (a INT, b VARCHAR(10));
|
||||
INSERT INTO t1 VALUES (1,'11');
|
||||
INSERT INTO t1 VALUES (1,'12');
|
||||
INSERT INTO t1 VALUES (2,'21');
|
||||
INSERT INTO t1 VALUES (2,'22');
|
||||
INSERT INTO t1 VALUES (3,'31');
|
||||
INSERT INTO t1 VALUES (3,'32');
|
||||
CREATE PROCEDURE p1(a_a INT)
|
||||
AS
|
||||
v_a INT;
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_a INT) IS SELECT a,b FROM t1 WHERE a=p_a;
|
||||
BEGIN
|
||||
OPEN c(a_a);
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
INSERT INTO t2 VALUES (v_a,v_b);
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1(1);
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 11
|
||||
1 12
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Two parameters in WHERE clause
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(10));
|
||||
CREATE TABLE t2 (a INT, b VARCHAR(10));
|
||||
INSERT INTO t1 VALUES (1,'11');
|
||||
INSERT INTO t1 VALUES (1,'12');
|
||||
INSERT INTO t1 VALUES (2,'21');
|
||||
INSERT INTO t1 VALUES (2,'22');
|
||||
INSERT INTO t1 VALUES (3,'31');
|
||||
INSERT INTO t1 VALUES (3,'32');
|
||||
CREATE PROCEDURE p1(a_a INT, a_b VARCHAR)
|
||||
AS
|
||||
v_a INT;
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_a INT, p_b VARCHAR) IS SELECT a,b FROM t1 WHERE a=p_a AND b=p_b;
|
||||
BEGIN
|
||||
OPEN c(a_a, a_b);
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
INSERT INTO t2 VALUES (v_a,v_b);
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END;
|
||||
$$
|
||||
CALL p1(1,'11');
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
1 11
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# Parameters in WHERE and HAVING clauses
|
||||
#
|
||||
CREATE TABLE t1 (name VARCHAR(10), value INT);
|
||||
INSERT INTO t1 VALUES ('but',1);
|
||||
INSERT INTO t1 VALUES ('but',1);
|
||||
INSERT INTO t1 VALUES ('but',1);
|
||||
INSERT INTO t1 VALUES ('bin',1);
|
||||
INSERT INTO t1 VALUES ('bin',1);
|
||||
INSERT INTO t1 VALUES ('bot',1);
|
||||
CREATE PROCEDURE p1 (arg_name_limit VARCHAR, arg_total_limit INT)
|
||||
AS
|
||||
v_name VARCHAR(10);
|
||||
v_total INT;
|
||||
-- +0 is needed to work around the bug MDEV-11081
|
||||
CURSOR c(p_v INT) IS
|
||||
SELECT name, SUM(value + p_v) + 0 AS total FROM t1
|
||||
WHERE name LIKE arg_name_limit
|
||||
GROUP BY name HAVING total>=arg_total_limit;
|
||||
BEGIN
|
||||
FOR i IN 0..1
|
||||
LOOP
|
||||
OPEN c(i);
|
||||
LOOP
|
||||
FETCH c INTO v_name, v_total;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
SELECT v_name, v_total;
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
END LOOP;
|
||||
END;
|
||||
$$
|
||||
CALL p1('%', 2);
|
||||
v_name v_total
|
||||
bin 2
|
||||
v_name v_total
|
||||
but 3
|
||||
v_name v_total
|
||||
bin 4
|
||||
v_name v_total
|
||||
bot 2
|
||||
v_name v_total
|
||||
but 6
|
||||
CALL p1('b_t', 0);
|
||||
v_name v_total
|
||||
bot 1
|
||||
v_name v_total
|
||||
but 3
|
||||
v_name v_total
|
||||
bot 2
|
||||
v_name v_total
|
||||
but 6
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# One parameter in LIMIT clause
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b VARCHAR(10));
|
||||
INSERT INTO t1 VALUES (1,'b1');
|
||||
INSERT INTO t1 VALUES (2,'b2');
|
||||
INSERT INTO t1 VALUES (3,'b3');
|
||||
INSERT INTO t1 VALUES (4,'b4');
|
||||
INSERT INTO t1 VALUES (5,'b5');
|
||||
INSERT INTO t1 VALUES (6,'b6');
|
||||
CREATE PROCEDURE p1(a_a INT)
|
||||
AS
|
||||
v_a INT;
|
||||
v_b VARCHAR(10);
|
||||
CURSOR c (p_a INT) IS SELECT a,b FROM t1 ORDER BY a LIMIT p_a;
|
||||
BEGIN
|
||||
CREATE TABLE t2 (a INT, b VARCHAR(10));
|
||||
OPEN c(a_a);
|
||||
LOOP
|
||||
FETCH c INTO v_a, v_b;
|
||||
EXIT WHEN c%NOTFOUND;
|
||||
INSERT INTO t2 VALUES (v_a,v_b);
|
||||
END LOOP;
|
||||
CLOSE c;
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
END;
|
||||
$$
|
||||
CALL p1(1);
|
||||
a b
|
||||
1 b1
|
||||
CALL p1(3);
|
||||
a b
|
||||
1 b1
|
||||
2 b2
|
||||
3 b3
|
||||
CALL p1(6);
|
||||
a b
|
||||
1 b1
|
||||
2 b2
|
||||
3 b3
|
||||
4 b4
|
||||
5 b5
|
||||
6 b6
|
||||
DROP TABLE t1;
|
||||
DROP PROCEDURE p1;
|
||||
#
|
||||
# End of MDEV-10597 Cursors with parameters
|
||||
#
|
||||
|
Reference in New Issue
Block a user