Процедура MySQL8 - использование параметров в курсоре - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь использовать входные параметры хранимой процедуры в пределах курсора процедуры. Вызов процедуры следующим образом приводит к ошибке

--                               -role-      -table-  -cond- 
CALL grantRoleToUsersFromWhere('Student', 'studenten', true);

Код ошибки: 1146. Таблица 'uni4.utable' не существует

Это говорит о том, что параметр 'userTable' не был записан в переменную 'uTable' ИЛИ ​​'uTable' вообще не распознается как переменная оператором курсора.

Я пробовал разные подходы для хранения / использования параметров. Например, используйте их напрямую или сохраните в переменной с помощью оператора SET. Однако, если я попытаюсь использовать SET uTable = userTable; до объявления курсора MySQL WorkBench не примет объявление процедуры.

Я потратил довольно много времени на это, но мне кажется, что я упускаю важную, но простую часть: -)

DROP PROCEDURE IF EXISTS grantRoleToUsersFromWhere;

DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE grantRoleToUsersFromWhere(IN grantRole VARCHAR(30), IN userTable VARCHAR(30), IN addCondition VARCHAR(50))

BEGIN
    DECLARE workUser VARCHAR(30) default '';    
    DECLARE gRole VARCHAR(30) default grantRole;
    DECLARE uTable VARCHAR(30) default userTable;
    DECLARE aCond VARCHAR(50) default addCondition;

    DECLARE cur1 CURSOR FOR SELECT Name FROM uTable WHERE aCond;

    OPEN cur1;    
    read_loop: LOOP
        FETCH cur1 INTO workUser;
        GRANT gRole TO workUser;
    END LOOP;    
    CLOSE cur1; 
END $$
DELIMITER ;

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

'ОБЪЯВИТЬ КУРСОР cur1 ДЛЯ ВЫБРАТЬ ИМЯ ИЗ ИМЕННОЙ ГДЕ aCond;' невозможно mysql не выполняет подстановку переменных (для имени таблицы). Ваше чтение l oop бесконечно, потому что вы не объявляете обработчик продолжения и проверяете, что не найдено в чтении l oop.

0 голосов
/ 27 апреля 2020

Создание динамических c курсоров напрямую невозможно. Однако вы можете использовать VIEW для достижения того же. См. образец .

CREATE PROCEDURE p1 (select_statement VARCHAR(255))
BEGIN
  DECLARE v1,v2 VARCHAR(255);
  DECLARE c CURSOR FOR SELECT * FROM t;
  SET @v = CONCAT('create temporary table t as ',select_statement);
  PREPARE stmt1 FROM @v;
  EXECUTE stmt1;
  OPEN c;
  FETCH c INTO v1,v2;
  SELECT v1,v2;
END//
...