Вопрос

Я хочу сделать столбец в отношениях, немодифицированном по причинам последовательности.

Предыстория заключается в том, что у меня есть отношения: n, где отношение «соединения» имеет дополнительные значения. Я не хочу, чтобы кто -то мог изменить идентификаторы партнеров по отношениям.

Что я придумал до сих пор:

Создание триггера, который проверяет, такое новое значение такого же, как старое значение. Но я не знаю, как отрицать действие обновления, если условие оказалось как истинное.

Вот мой триггер до сих пор:

CREATE TRIGGER deny_nton_change BEFORE UPDATE ON Schueler_in_Klasse
FOR EACH ROW BEGIN
    IF NEW.Schueler_ID != OLD.Schueler_ID OR NEW.Klasse_ID != OLD.Klasse_ID THEN

    END IF;
END;
Это было полезно?

Решение

Вместо того, чтобы прервать обновление, просто переопределите его?

...
FOR EACH ROW BEGIN
    SET NEW.Schueler_ID = OLD.Schueler_ID;
    SET NEW.Klasse_ID = OLD.Klasse_ID;
END

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

Довольно хороший и чистый способ прервать и вернуть читаемое сообщение об ошибке, используя сигнал:

Сигнал sqlstate '45000' set message_text = 'schueler_id и klasse_id не может быть изменена!';

Убедитесь, что ваша версия MySQL поддерживает это, она была введена в MySQL 5.5. В более ранних версиях вам нужны взломы, такие как вставка не существующего поля в не существующую таблицу.

Как упоминает GBN, перезапись новых значений со старыми также является хорошим вариантом.

Я на самом деле научился обратно-задумчивому подходу к абортированию триггеров. Анкет Это очень грубое, но работает, потому что обработка сигнала не реализована на языке хранимой процедуры MySQL. Это может быть в лучшем случае эмулировать.

Глава 11, страницы 254-256 книги MySQL хранящаяся процедура Программирование под подзаголовом 'Проверка данных с помощью триггеров' предлагает сделать выбор строки символов в фиктивное целое число (с точки зрения синтаксиса, это правильно, но умирает от исполнения [без каламбура]):

CREATE TRIGGER deny_nton_change BEFORE UPDATE ON Schueler_in_Klasse 
FOR EACH ROW BEGIN
    DECLARE dummy INT; 
    IF NEW.Schueler_ID != OLD.Schueler_ID OR NEW.Klasse_ID != OLD.Klasse_ID THEN 
        SELECT 'Cannot Carry Out This Trigger Any Further'
        INTO dummy FROM table_you_know_does_not_exist WHERE 1=1 LIMIT 1;
    END IF; 
END; 

На самом деле можно сделать это аккуратно без использования триггеров, если вы используете InnoDB.

Создайте другую таблицу с одним столбцом. Этот столбец должен иметь внешний ключ (отсюда и требование InnoDB в этом решении), который указывает на неизменную столбец исходной таблицы.

Поместите ограничение, как «Ограничение обновления».

В итоге:

CREATE TABLE original (
     ....
     immutable_column ...
     INDEX index1(immutable_column)
     ....
) ENGINE=INNODB;

CREATE TABLE restricter (
     .....
     col1,
     INDEX index2(col1),
     FOREIGN KEY (col1) REFERENCES original (immutable_colum) ON UPDATE RESTRICT ON DELETE CASCADE
) ENGINE=INNODB;

Основываясь на комбинации всех ответов, которые я прочитал, это то, что сработало для меня:

delimiter $$ -- You may need this or not (in my visual client I need it, directly in console I don't)
create trigger deny_nton_change before update on surveys
for each row begin
    if new.Schueler_ID != old.Schueler_ID OR new.Klasse_ID != old.Klasse_ID then
      signal sqlstate '45000' set message_text = 'My own Error: Field is immutable';
    end if;
end$$
delimiter ; -- You may need this or not
Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top