MySQL триггер для обновления поля до значения id

StackOverflow https://stackoverflow.com/questions/1211792

  •  06-07-2019
  •  | 
  •  

Вопрос

Я хотел бы иметь триггер для выполнения следующей операции для вставленных записей:

 # pseudocode
 if new.group_id is null
    set new.group_id = new.id
 else
    # don't touch it
 end

Более четко: скажем, у меня есть одна таблица с тремя столбцами: id первичный ключ, group_id int, value varchar.

Когда я вставляю с group_id вот так:

INSERT INTO table(value, group_id) VALUES ('a', 10)

Я бы хотел иметь:

id | group_id | value
---+----------+------
 1 |       10 | a

но когда я опускаю group_id :

INSERT INTO table(value) VALUES ('b')

он должен быть автоматически установлен на id этой записи:

id | group_id | value
---+----------+------
 2 |        2 | b

Возможно ли это с помощью триггера? (Я знаю, что могу обновить запись после вставки, но наличие триггера было бы лучше.)

Это было полезно?

Решение

Я не знаю ни одного способа сделать это одним оператором, даже используя триггер.

Триггерное решение, предложенное @Lucky, будет выглядеть в MySQL следующим образом:

CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
  SET NEW.group_id = COALESCE(NEW.group_id, NEW.id);
END

Однако есть проблема. На этапе BEFORE INSERT автоматически сгенерированное значение id еще не было сгенерировано. Так что если group_id равен нулю, по умолчанию используется NEW.id , который всегда равен 0.

Но если вы измените этот триггер на срабатывание во время фазы AFTER INSERT , чтобы у вас был доступ к сгенерированному значению NEW.id , вы не сможете изменить столбец значения.

MySQL не поддерживает выражения для DEFAULT столбца, поэтому вы не можете также объявить это поведение в определении таблицы.

Единственное решение - выполнить INSERT , а затем сразу же выполнить UPDATE , чтобы изменить group_id , если он не установлен.

INSERT INTO MyTable (group_id, value) VALUES (NULL, 'a');
UPDATE MyTable SET group_id = COALESCE(group_id, id) WHERE id = LAST_INSERT_ID();

Другие советы

Я отвечаю здесь, как и в принятом ответе Билл Карвин утверждает:

  

На этапе BEFORE INSERT автоматически сгенерированное значение id не было   генерируется еще. Так что если group_id равен нулю, по умолчанию используется NEW.id, который   всегда 0.

<Ч>

У меня есть ответ на этот вопрос - для OP (и для посетителей), вот несколько моментов: Вы не можете обновить таблицу, из которой вызывается триггер, для этого вы получите Ошибка 1442 :

Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

1. Обновить новую строку Используйте триггер BEFORE INSERT ON , чтобы вы могли обновить все поля для новой строки, которые могут быть доступны через оператор NEW, т.е.

set NEW.group_id = NEW.id

2. Получите значение auto_increment перед вставкой :

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='MyTable'

Подводя итог - триггер SQL для d будет выглядеть следующим образом:

DELIMITER //
DROP TRIGGER IF EXISTS MyTrigger//
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
    IF new.group_id IS NULL
        set @auto_id := (SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES
                         WHERE TABLE_NAME='MyTable' AND TABLE_SCHEMA=DATABASE() ); 
        set NEW.group_id = @auto_id;
    ENF IF;
END;
//
DELIMITER ;

Это работает для меня

DELIMITER $
CREATE TRIGGER `myTriggerNameHere`
BEFORE INSERT ON `table` FOR EACH ROW
BEGIN
    SET NEW.group_id = IF(NEW.group_id IS NULL, LAST_INSERT_ID()+1, NEW.group_id);
END;
$
DELIMITER ;

Я считаю, что это будет работать для вас

У меня есть две таблицы

test_b: a_id, value
test_c: a_id, value

А вот триггер на вставке теста б. Он проверяет, имеет ли значение a_id значение NULL и вставляет ли он 0

CREATE TRIGGER test_b AFTER INSERT ON test_b
  FOR EACH ROW 
    INSERT INTO test_c (a_id, value) VALUES (IFNULL(NEW.a_id, 0),NEW.value)

Этот триггер должен делать то, что вы просили.

   CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
          IF new.group_id IS NULL
            SET new.group_id = new.id
          END IF
      END;

Он скопирован из очень похожего примера в документации MYSQL. страница.

В этой ситуации триггер кажется излишним. Просто примените значение по умолчанию.

CREATE TABLE `test` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `value` varchar(100) NOT NULL,
    `group_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2'
)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top