Не могу указать имя таблицы в хранимой процедуре MySQL

0

Я массово присваиваю новые идентификационные номера вещам в БД, чтобы освободить место для некоторых вещей в начале каждой таблицы. Я создал процедуру, которая работает, но когда я пытаюсь добавить входные параметры для разрешения сценариев, она не может найти таблицу

delimiter |
CREATE PROCEDURE changeID 
( IN in_table_name varchar(64)) 
BEGIN 
  DECLARE done INT DEFAULT FALSE;
  DECLARE a,b INT DEFAULT 800000;
  DECLARE cur1 CURSOR FOR SELECT id  FROM in_table_name ORDER BY id;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
  FETCH cur1 INTO b;
    IF done THEN
      LEAVE read_loop;
    END IF;
        UPDATE in_table_name SET id = a + 1 where id = b;
        SET a = a+1;

END LOOP;
  CLOSE cur1;
END; 
|
delimiter ;

Когда я запускаю это с помощью call changeID('users'), я получаю ошибку:

[Err] 1146 - Table 'databaseName.in_table_name' doesn't exist

Я надеялся пройти через простой список таких команд, чтобы он мог запускаться без присмотра, а не вручную изменять in_table_name между каждым исполнением:

call changeID('users');
call changeID('appointments');
call changeID('groups');
Теги:
stored-procedures

2 ответа

0
Лучший ответ

KCason сделал меня в правильном направлении, но мне нужно было немного поработать над тем, чтобы первая часть работала над подсказками здесь: https://forums.mysql.com/read.php?98,138495,138908#msg- 138908.

DROP PROCEDURE
IF EXISTS 'workingversion';

delimiter |

CREATE PROCEDURE 'workingversion' (IN tableName VARCHAR(100))
BEGIN

DECLARE done INT DEFAULT 0 ;
DECLARE a,
 b INT DEFAULT 800000 ;
DROP VIEW IF EXISTS v1; 
SET @stmt_text = CONCAT("CREATE VIEW v1 AS SELECT id FROM ",    tableName,  " ORDER BY id") ; 
PREPARE stmt
FROM
    @stmt_text ; EXECUTE stmt ; DEALLOCATE PREPARE stmt ;
BEGIN

DECLARE cur1 CURSOR FOR SELECT * FROM v1 ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'
SET done = 1 ; OPEN cur1 ;
REPEAT
    FETCH cur1 INTO b ;
IF NOT done THEN
SET @Query = CONCAT('UPDATE ',tableName,' SET 'id' = ',a+1,' WHERE 'id'=',b);
PREPARE stmt FROM @Query;
EXECUTE stmt;

        SET a = a+1;
END
IF ; UNTIL done
END
REPEAT
    ; CLOSE cur1 ;
END ;
END
1

Вы не можете динамически передавать имя таблицы в запросе, однако вы можете конкатенировать строку, а затем выполнить ее как инструкцию. Вы, конечно, хотите быть осторожными и обеспечить, чтобы эти данные были дезинфицированы и т.д. Я не смог проверить это, но что-то в этом роде должно заставить вас идти.

...
END IF;

SET @Query = CONCAT('UPDATE ',in_table_name,' SET 'id' = ',a+1,' WHERE 'id'=',b);
PREPARE stmt FROM @Query;
EXECUTE stmt;
...

https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html

  • 0
    Спасибо, я пытаюсь использовать то, чему вы меня учили в пределах курсора выбора, но я продолжаю получать сообщение об ошибке для любой строки после этого: SET @in_table_name = in_table_name varchar(50); Я пробовал с varchar и без него, DECLARE вместо SET, есть ли причина, по которой я не могу установить его вне цикла?
  • 0
    Я не вижу строки, которую вы упомянули в своем комментарии. Почему вы сбрасываете переменную? Какие ошибки вы получаете? Почему бы вам не обновить свой вопрос, чтобы его можно было отформатировать?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню