Не удается правильно объявить переменную в цикле процедуры

Это сводит меня с ума. Я не гуру 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 столбцов. Либо это, либо мне не хватает фундаментальной концепции.

Другие вопросы по тегам