MYSQL |服务提供商 | CURSOR - 将光标获取到变量 return null
MYSQL | SP | CURSOR - Fetch cursor into variable return null
我想:
- 创建临时 table.
- 将部分数据插入临时 table。
- 运行 在 temporary.user_id 字段上循环。
- 在数据操作和计算后更新每一行。
第 3 步的问题,我从游标中得到 user_id=NULL 而不是一个整数。
CREATE PROCEDURE user_demo_sp()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE current_user INT;
DECLARE cur CURSOR FOR SELECT user_id FROM users_temp; -- Cursor on temp table
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- Create a table
DROP temporary table if exists `users_temp` ;
CREATE temporary table `users_temp` (
user_id INT(11) NOT NULL,
aggregation_column INT(11) NOT NULL
);
-- Fill table
INSERT INTO users_temp SELECT user_id from users where condition ="condition";
OPEN cur;
read_loop: LOOP
FETCH cur INTO current_user;
IF done THEN
LEAVE read_loop;
END IF;
select current_user; -- Return NULL
END LOOP;
CLOSE cur;
END;
you need to fill your temp table before declaring the cursor on it (just use nested Begin...END blocks):
CREATE PROCEDURE user_demo_sp()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE current_user INT;
temp table
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- Create a table
DROP temporary table if exists `users_temp` ;
CREATE temporary table `users_temp` (
user_id INT(11) NOT NULL,
aggregation_column INT(11) NOT NULL
);
-- Fill table
INSERT INTO users_temp SELECT user_id from users where condition ="condition";
Begin
DECLARE cur CURSOR FOR SELECT user_id FROM users_temp; -- Cursor on
OPEN cur;
read_loop: LOOP
FETCH cur INTO current_user;
IF done THEN
LEAVE read_loop;
END IF;
select current_user; -- Return NULL
END LOOP;
CLOSE cur;
End;
END;
Also in scenarios like this actually you don't need a temp table you
can declare the cursor on the select which you used to fill temptale
我想:
- 创建临时 table.
- 将部分数据插入临时 table。
- 运行 在 temporary.user_id 字段上循环。
- 在数据操作和计算后更新每一行。
第 3 步的问题,我从游标中得到 user_id=NULL 而不是一个整数。
CREATE PROCEDURE user_demo_sp()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE current_user INT;
DECLARE cur CURSOR FOR SELECT user_id FROM users_temp; -- Cursor on temp table
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- Create a table
DROP temporary table if exists `users_temp` ;
CREATE temporary table `users_temp` (
user_id INT(11) NOT NULL,
aggregation_column INT(11) NOT NULL
);
-- Fill table
INSERT INTO users_temp SELECT user_id from users where condition ="condition";
OPEN cur;
read_loop: LOOP
FETCH cur INTO current_user;
IF done THEN
LEAVE read_loop;
END IF;
select current_user; -- Return NULL
END LOOP;
CLOSE cur;
END;
you need to fill your temp table before declaring the cursor on it (just use nested Begin...END blocks):
CREATE PROCEDURE user_demo_sp()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE current_user INT;
temp table
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- Create a table
DROP temporary table if exists `users_temp` ;
CREATE temporary table `users_temp` (
user_id INT(11) NOT NULL,
aggregation_column INT(11) NOT NULL
);
-- Fill table
INSERT INTO users_temp SELECT user_id from users where condition ="condition";
Begin
DECLARE cur CURSOR FOR SELECT user_id FROM users_temp; -- Cursor on
OPEN cur;
read_loop: LOOP
FETCH cur INTO current_user;
IF done THEN
LEAVE read_loop;
END IF;
select current_user; -- Return NULL
END LOOP;
CLOSE cur;
End;
END;
Also in scenarios like this actually you don't need a temp table you can declare the cursor on the select which you used to fill temptale