2013-04-18 2 views
0

Я пытаюсь создать динамическую команду ALTER TABLE, но некоторая команда будет сгенерирована из запроса. Проблема в том, что я хочу использовать это в триггере!Использование запроса в ALTER TABLE в CREATE TRIGGER

Попытка 1:

ALTER TABLE `redinfomanager` CHANGE `Unterkategorie` `Unterkategorie` ENUM(("SELECT GROUP_CONCAT(CONCAT('\'', REPLACE(`Unterkategorien`, '\r\n', '\',\''), '\'') SEPARATOR ',') FROM `kategorien` GROUP BY '1'")) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL; 

Попытка 2:

SELECT @tmp:=GROUP_CONCAT(CONCAT('\'', REPLACE(`Unterkategorien`, '\r\n', '\',\''), '\'') SEPARATOR ',') FROM `kategorien` GROUP BY '1'; 
SET @query=CONCAT('ALTER TABLE `redinfomanager` CHANGE `Unterkategorie` `Unterkategorie` ENUM(', @tmp, ') CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL'); 
PREPARE stmt FROM @query; 
EXECUTE stmt; 

Покушение 3:

SET @kat = (SELECT GROUP_CONCAT(CONCAT('\'', REPLACE(`Unterkategorien`, '\r\n', '\',\''), '\'') SEPARATOR ',') FROM kategorien GROUP BY '1'); 
PREPARE stmt FROM 'ALTER TABLE redinfomanager CHANGE Unterkategorie Unterkategorie ENUM(?) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL'; 
EXECUTE stmt USING @kat; 

Он говорит мне:

1064 - Y ou имеет ошибку в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '; ГОТОВИТЬ STMT ОТ 'ALTER TABLE redinfomanager CHANGE Unterkategorie `Unte' в строке 1

Как я могу это сделать?

И что это за ошибка?

+0

Выполнение команды «ALTER TABLE» из триггера, вероятно, является «действительно» плохой идеей. «ALTER TABLE» блокирует таблицу и часто вынуждает переписывать всю таблицу, что может быть очень медленным если таблица большая. Если у вас есть столбец, который не имеет четко определенного набора возможных значений, не используйте 'ENUM()'. Вместо этого используйте 'VARCHAR' или подобное. – duskwuff

+0

Ну, таблица не слишком большая. Набор вряд ли изменится вообще, но прямо сейчас я нахожусь на этапе тестирования, поэтому у меня нет времени на редактирование всех изменений вручную, так как я могу изменить набор, чтобы увидеть, что происходит. Но есть ли способ сделать эту работу ??? – BrainStone

+1

Не используйте 'ENUM'. Столбец 'VARCHAR' соответствующего размера будет вести себя почти одинаково и позволит вам использовать любое строковое значение без изменения таблицы. – duskwuff

ответ

1

Кажется, что вы меняете значение ENUM на второй таблице после каждой вставки на первой таблице? Почему бы просто не сделать это foreign key constraint. Это потребует любые значения, которые вы хотите поместить в таблице 2 будет иметь значение из таблицы 1. Это будет гораздо более эффективным, тоже:

Просто пример (sqlfiddle link):

CREATE TABLE category (
    id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, 
    description VARCHAR(50) 
); 

CREATE TABLE thing (
    id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, 
    cat_id INTEGER, 
    description VARCHAR(50), 
    FOREIGN KEY (cat_id) REFERENCES category(id) 
); 

INSERT INTO category (description) 
VALUES 
    ('Category 1') 
    ,('Category 2'); 

INSERT INTO thing (cat_id, description) 
VALUES 
    (1, 'Thing 1') 
    ,(1, 'Thing 2') 
    ,(2, 'Thing 3'); 

INSERT INTO thing (cat_id, description) 
VALUES 
    (3, 'Imma Fail!') 

Если вы запустите его, третья вставка потерпит неудачу, потому что нет id из 3 в таблице category.

+0

Похоже, что ссылка sqlfiddle не совпадает с тем, что у меня выше ... это, вероятно, не спасает, когда вы создаете схему с ошибкой (что, вероятно, лучше сделать ':)'). Но если вы скопируете и вставьте вышеописанное, вы получите следующую ошибку при попытке построить схему: «Ошибка создания схемы: невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа завершено с ошибкой (' 'db_2_f1164'''''thing' ', CONSTRAINT' 'thing_ibfk_1'' FOREIGN KEY (' 'cat_id'') ССЫЛКИ' 'category'' (' 'id'')):' – bhamby

+0

Спасибо! Это работает! А также благодарю вас за то, что вы научили меня чему-то совершенно новому для меня! – BrainStone

Смежные вопросы