2013-09-23 4 views
2

Мне нужно скопировать идентификатор auto_increment ID-значение в другой столбец при вставке. Я думаю, мне нужен триггер «после вставки», потому что в противном случае новый идентификатор неизвестен ..?MySQL Trigger: копировать значение auto_increment в другой столбец при вставке

Я попытался это:

IF NEW.content IS NULL THEN 
    SET NEW.content = NEW.id; 
END IF 

Но он жалуется:

Updating of NEW row is not allowed in after trigger

+0

Каково имя вашей таблицы? –

+0

Стол-имя «примечания» – kvdmolen

+0

CREATE TRIGGER insert_example ДОПОЛНИТЕЛЬНЫЙ ВСТАВИТЬ Пример ДЛЯ КАЖДОГО РУКА SET NEW.object_id = NEW.id; Попробуй это. –

ответ

0

Да, это невозможно с триггерами. Лучшее, что вы могли бы сделать, это то, что вы заменяете оператор INSERTCALL some_procedure(values...) и реализуете вышеприведенную логику. (при условии, что вы можете изменить SQL на стороне приложения).

Другой (но уродливее) решение для установки события, которые периодически фиксирует ваши записи, где content=NULL

0

Как ОП отметил NEW.id не будет работать с автоматическим приращением; можно использовать следующий триггер (использовать на свой страх и риск). Попробуй это.

CREATE TRIGGER insert_example 
     BEFORE INSERT ON notes 
     FOR EACH ROW 
     SET NEW.content = (
      SELECT AUTO_INCREMENT 
      FROM information_schema.TABLES 
      WHERE TABLE_SCHEMA = DATABASE() 
      AND TABLE_NAME = 'notes' 
    ); 
+0

Точно так же я думал о триггере INSERT с NEW.content = LAST_INSERT_ID() + 1, но я думаю, что это тоже рискованно .. – kvdmolen

+0

да. вы можете сами выбирать. –

+0

Не гарантируется, что следующим значением auto_increment является 'LAST_INSERT_ID() + 1'. См. [Autoinc_lock_mode for INNODB] (http://dev.mysql.com/doc/refman/5.5/en/innodb-auto-increment-handling.html) –

0

бит из латать, по вы можете просто сказать

DELIMITER $$ 
CREATE TRIGGER sometrigger 
AFTER INSERT ON sometable 
BEGIN 
    UPDATE sometable SET content = NEW.id WHERE id = NEW.id; 
END $$ 

обновления в (же) таблицу с помощью полного запроса, а не пытаться использовать SET.

или даже

DELIMITER $$ 
CREATE TRIGGER sometrigger 
AFTER INSERT ON sometable 
BEGIN 
    UPDATE sometable SET content = id WHERE content is null; 
END $$ 

(который является своего рода похожи на предложение Allita о событии)

+0

Он не будет работать в MySQL. Вы не можете выполнить какой-либо оператор DML в триггере в таблице, на которой указан этот триггер. – peterm

+0

Latter дает еще одну ошибку: «Невозможно обновить« заметки »в хранимой функции/триггере, потому что она уже используется оператором, который вызывал эту хранимую функцию/триггер». – kvdmolen

+0

Ах, извините. Я признаю, что не пробовал. Я использовал триггеры для вставки (другой) новой строки, но не попробовал обновление, только предположил, что это сработает. Я не могу понизить свой собственный ответ! – barryhunter

0

Если вы действительно нужно это поведение по какой-то причине вы можете достичь его с помощью отдельной таблицы для последовательности и BEFORE INSERT триггер

Для начала вам нужна простая таблица для последовательности, которая может выглядеть как

CREATE TABLE table1_seq 
(
    id int not null auto_increment primary key 
); 

Тогда ваша фактическая схема таблицы может выглядеть

CREATE TABLE table1 
(
    id int not null default 0 primary key, 
    content int 
); 

теперь спускового

DELIMITER $$ 
CREATE TRIGGER tg_ai_table1 
BEFORE INSERT ON table1 
FOR EACH ROW 
BEGIN 
    INSERT INTO table1_seq() VALUES(); 
    SET NEW.id = LAST_INSERT_ID(), NEW.content = COALESCE(NEW.content, NEW.id); 
END$$ 
DELIMITER ; 

Теперь, если вы вставляете в table1

INSERT INTO table1() VALUES (NULL),(-1); 

Вы будете иметь

 
| ID | CONTENT | 
|----|---------| 
| 1 |  1 | 
| 2 |  -1 | 

Вот SQLFiddle демо

+0

@kvdmolen Помогло ли это? Вам нужна дополнительная помощь по вашему вопросу? – peterm

+0

Ответ: невозможно использовать триггеры.Я предпочитаю более простые обходные пути (см. Комментарий в начальном вопросе), или мне нужно будет создать его на прикладном уровне. Спасибо за вашу помощь! – kvdmolen

2

В этом коде

CREATE TRIGGER insert_example 
    BEFORE INSERT ON notes 
    FOR EACH ROW 
    SET NEW.content = (
     SELECT AUTO_INCREMENT 
     FROM information_schema.TABLES 
     WHERE TABLE_SCHEMA = DATABASE() 
     AND TABLE_NAME = 'notes' 
); 

я сделал что-то вроде этого

SET NEW.content = (SELECT CONCAT('ID',LPAD(AUTO_INCREMENT, number,'0')) 
FROM information_schema.TABLES 
WHERE TABLE_SCHEMA = DATABASE() 
AND TABLE_NAME = 'notes'); 

в случае, если вы используете UNSIGNED_ZEROFILL на поле ид ... и вам может понадобиться специальный «открытый» идентификатор ...

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