Не удается правильно объявить переменную в цикле процедуры
Это сводит меня с ума. Я не гуру MySQL в любом случае. Моя цель - добавить большое количество столбцов в таблицу. Я пробовал это несколькими способами, и процедура задыхается на DECLARE @FooA NVARCHAR(MAX);. Понятия не имею, почему.
Я ценю любые указатели...
USE mydatabase;
DELIMITER $$
DROP PROCEDURE IF EXISTS RepeatLoopProc$$
CREATE PROCEDURE RepeatLoopProc()
BEGIN
DECLARE x INT;
DECLARE sn VARCHAR(30);
DECLARE dr VARCHAR(48);
DECLARE @FooA NVARCHAR(MAX);
SET x = 0;
WHILE (x <= 150) DO
SET sn = CONCAT('drivesn_', x);
SET dr = CONCAT('driveinf_', x);
SET x = x + 1;
SET @FooA = 'ALTER TABLE DRIVE_MASTER ADD ' + sn + ' VARCHAR(30), ADD ' + dr + ' VARCHAR(48)';
EXEC sp_executesql @FooA;
END WHILE;
END$$
DELIMITER ;
Когда я делаю это, я получаю:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@FooA NVARCHAR(MAX);
Мой лоб сжимается от удара в мой стол.
Конечной целью является добавление столбцов driven_0, driveinf_0, Driversn_1, Driveinf_1 и т. Д. Вплоть до Driversn_150 и Driveinf_150. Введите VARCHAR(30) и VARCHAR(48) для каждого соответственно.
2 ответа
@variables не являются DECLAREd, а идентификаторы объявленных переменных не начинаются с @.
Кроме того, операторы ALTER обычно воссоздают таблицу за кулисами (что-то вроде CREATE TABLE newversion... INSERT INTO newversion SELECT * FROM oldversion ... DROP TABLE oldversion ... RENAME newversion). Так что вам было бы гораздо лучше создать в цикле один оператор ALTER и выполнить его только один раз.
Пример:
...
SET @FooA = 'ALTER TABLE DRIVE_MASTER';
SET x = 0;
WHILE (x <= 150) DO
SET sn = CONCAT('drivesn_', x);
SET dr = CONCAT('driveinf_', x);
SET @FooA = CONCAT(@FooA
, CASE WHEN x != 0 THEN ', ' ELSE '' END
, 'ADD ', sn, ' VARCHAR(30), ADD ', dr, ' VARCHAR(48)'
);
SET x = x + 1;
END WHILE;
EXEC sp_executesql @FooA;
...
... но то, что Бармар сказал в комментариях, является хорошим советом, вы, вероятно, должны просто иметь другую таблицу, что-то вроде DRIVE_MASTER_DETAILS(x int, sn VARCHAR(30), dr VARCHAR(48))
У меня уже есть несколько таблиц. В основном я использую это для каталогизации серийных номеров дисков в хостах. Хост может иметь до 150 дисков. Другие таблицы содержат информацию о сетевом интерфейсе (macaddrs и т. Д.). Все связаны общим значением индекса. Для системы с 150 дисководами я не вижу другого пути, кроме 150 столбцов. Либо это, либо мне не хватает фундаментальной концепции.