Ошибка в моем синтаксисе SQL для создания или выполнения триггера

#mysql #sql #database #triggers

#mysql #sql #База данных #триггеры

Вопрос:

value_table

  • автоматическое увеличение идентификатора не является уникальным
  • primary_object_id
  • user_id
  • значение

group_table

  • автоматическое увеличение идентификатора не является уникальным
  • primary_object_id
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

У меня есть две таблицы, в одной из которых хранятся значения (value_table), а в другой (group_value) хранится количество значений. В group_table 1-7 имеется около 7 числовых столбцов.

Каждый пользователь может присвоить значение от 1 до 7 объекту, который имеет id=primary_object_id, а также может обновлять его, поэтому мне нужно отслеживать, сколько пользователей присвоили 1 разным объектам с их соответствующим primary_object_id

Теперь я пытаюсь добиться того, что если они обновляют значение value_table, скажем, от 4 до 7, то я хочу обновить таблицу group_value и увеличить количество столбцов с именем 7 на 1 и уменьшить количество столбцов с именем 4

Я пришел к этому SQL, но он выдает синтаксическую ошибку

Я знаю, что ошибка есть только в этих двух последовательных операторах, потому что я попробовал статический оператор обновления, например

 update group_value set `7` = `7`   1 where id=OLD.primary_object_id;;
 

Приведенный выше оператор работает. Но как я мог бы использовать старые значения и новые значения для обновления значения в таблице group_value

 DELIMITER |

  CREATE TRIGGER UpdateCount AFTER UPDATE ON value_table FOR EACH ROW 

  BEGIN
      IF OLD.value <> NEW.value THEN
        UPDATE group_value SET `OLD.value` = `OLD.value` - 1 where id=OLD.primary_object_id;
        UPDATE group_value SET `NEW.value` = `NEW.value`   1 where id=OLD.primary_object_id;
      END IF;
  END;
|
DELIMITER ;
 

Комментарии:

1. Пожалуйста, добавьте определения таблиц полностью. и образцы данных

2. идентификатор в value_table не может быть первичным ключом, поскольку идентификатор столбца auto_increment должен быть первичным ключом.. пожалуйста, добавьте вывод show create table <имя_таблицы> для обеих таблиц

3. хорошо, просто обновляю через пару минут

Ответ №1:

Псевдоним таблицы и псевдоним столбца должны указываться отдельно.

Не

 UPDATE group_value SET `OLD.value` = `OLD.value` - 1 where id=OLD.id;
 

но

 UPDATE group_value SET `OLD`.`value` = `OLD`.`value` - 1 where id=OLD.id;
 

если пользователь обновляет свое значение в value_table с 4 до 5, мне нужно уменьшить количество 4 на 1 и увеличить количество 5 на 1 на вкладке group_value

Задача состоит в том, чтобы использовать значение столбца в качестве имени столбца? Это необходимо в подготовленном операторе, но это не разрешено в триггерах.

Единственным решением может быть:

 CREATE TRIGGER UpdateCount 
AFTER UPDATE 
ON value_table 
FOR EACH ROW 
BEGIN
    CASE OLD.value 
        WHEN 1 
        THEN UPDATE group_value SET `1` = `1` - 1 WHERE id=OLD.primary_object_id;
        WHEN 2 
        THEN UPDATE group_value SET `2` = `2` - 1 WHERE id=OLD.primary_object_id;
        WHEN 3 
        THEN UPDATE group_value SET `3` = `3` - 1 WHERE id=OLD.primary_object_id;
        WHEN 4 
        THEN UPDATE group_value SET `4` = `4` - 1 WHERE id=OLD.primary_object_id;
        WHEN 5 
        THEN UPDATE group_value SET `5` = `5` - 1 WHERE id=OLD.primary_object_id;
        WHEN 6 
        THEN UPDATE group_value SET `6` = `6` - 1 WHERE id=OLD.primary_object_id;
        WHEN 7 
        THEN UPDATE group_value SET `7` = `7` - 1 WHERE id=OLD.primary_object_id;
    END CASE;
    CASE NEW.value 
        WHEN 1 
        THEN UPDATE group_value SET `1` = `1`   1 WHERE id=NEW.primary_object_id;
        WHEN 2 
        THEN UPDATE group_value SET `2` = `2`   1 WHERE id=NEW.primary_object_id;
        WHEN 3 
        THEN UPDATE group_value SET `3` = `3`   1 WHERE id=NEW.primary_object_id;
        WHEN 4 
        THEN UPDATE group_value SET `4` = `4`   1 WHERE id=NEW.primary_object_id;
        WHEN 5 
        THEN UPDATE group_value SET `5` = `5`   1 WHERE id=NEW.primary_object_id;
        WHEN 6 
        THEN UPDATE group_value SET `6` = `6`   1 WHERE id=NEW.primary_object_id;
        WHEN 7 
        THEN UPDATE group_value SET `7` = `7`   1 WHERE id=NEW.primary_object_id;
    END CASE;
END
 

Но я настоятельно рекомендую нормализовать данные.

Комментарии:

1. Извините, но это не работает и не должно работать, потому что OLD — это не псевдоним таблицы, это триггерная переменная, которая поставляется с триггером обновления

2. Я знаю, что такое СТАРЫЙ псевдоним. И я вообще не могу найти причину для его цитирования, но вы можете, если хотите. Более того, я вообще не могу понять логику вашего триггера — в чем причина назначения OLD.value ? он все равно будет удален… И почему это выполняется в UPDATE, а не с помощью SET?

3. Я запросил СТАРОЕ, что я пробовал, но не знаю, как мне вставить в основном старое значение для имени столбца, в основном я сохраняю подсчеты, например, если пользователь обновляет свое значение в value_table с 4 до 5, тогда мне нужно уменьшить количество 4 на 1 и увеличить количество 5 на 1 в group_valueтаблица

4. @NimishBansal CREATE TABLE group_table (id AUTO_INCREMENT NOT NULL PRIMARY KEY, primary_object_id INT, group_number TINYINT, group_value INT); где group_number это число от 1 до 7 и group_value соответствует значению / сумме для этого объекта и группы.

5. @NimishBansal Дополнительно — я не вижу причины в синтетическом первичном ключе, тогда как у вас отличный естественный ключ : CREATE TABLE group_table (primary_object_id INT, group_number TINYINT, group_value INT, PRIMARY KEY (primary_object_id, group_number)); . Этот PK будет кластеризован и, следовательно, ему не нужно дополнительное дисковое пространство.