Удаление строки с ограничением внешнего ключа с помощью TRIGGER Before Delete в MySql - PullRequest
2 голосов
/ 11 июня 2019

У меня есть таблица с именем «estoque» с внешним ключом, который ссылается на другую таблицу с именем «produto».Затем я заполнил обе таблицы несколькими строками.

Вот мои таблицы:

    CREATE TABLE `produto` (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `NOME` varchar(45) NOT NULL,
      `PRECO` float NOT NULL,
      PRIMARY KEY (`ID`),
      UNIQUE KEY `NOME_UNIQUE` (`NOME`)
    );

    CREATE TABLE `estoque` (
      `ID` int(11) NOT NULL AUTO_INCREMENT,
      `ID_PRODUTO` int(11) NOT NULL,
      `QUANTIDADE_PRODUTO` int(11) NOT NULL DEFAULT '0',
      PRIMARY KEY (`ID`),
      KEY `fk_Estoque_Produto1_idx` (`ID_PRODUTO`),
      CONSTRAINT `fk_Estoque_Produto1` FOREIGN KEY (`ID_PRODUTO`)
      REFERENCES `produto` (`ID`)
    );

Мне нужно 'estoque', чтобы всегда ссылаться на все существующие строки в 'product'.Поэтому я создал AFTER INSERT и триггеры AFTER UPDATE для продукта:

    CREATE TRIGGER `cadastrar_novo_produto_no_estoque` 
    AFTER INSERT ON `produto` 
    FOR EACH ROW 
    INSERT IGNORE INTO estoque (ID_PRODUTO)
    VALUES (NEW.ID);

РЕДАКТИРОВАТЬ: На самом деле, поскольку я не могу изменить столбец «ID» для «produto», потому что это первичный ключЯ думаю, мне вообще не нужен триггер AFTER UPDATE.Я прав?

    CREATE TRIGGER `atualizar_novo_produto_no_estoque` 
    AFTER UPDATE ON `produto` 
    FOR EACH ROW 
    UPDATE estoque
        SET estoque.ID_PRODUTO = NEW.ID
        WHERE OLD.estoque.ID_PRODUTO = OLD.ID;

Теперь мне нужен триггер, чтобы при каждом удалении строки из «product» он также удалял соответствующую строку в «estoque».

I 'мы пытались создать такой как это:

    CREATE TRIGGER `deletar_produto_inexistente_no_estoque` 
    BEFORE DELETE ON `produto` 
    FOR EACH ROW DELETE FROM estoque
        WHERE estoque.ID_PRODUTO = ID;

Но всякий раз, когда я пытаюсь удалить строку из «produto», я получаю следующую ошибку:

ERROR 1175: 1175: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. 
SQL Statement:
DELETE FROM `papelaria`.`produto` WHERE (`ID` = '6')

Так что я пробовал сключевое слово OLD, как таковое:

        CREATE TRIGGER `deletar_produto_inexistente_no_estoque` 
        BEFORE DELETE ON `produto` 
        FOR EACH ROW DELETE FROM estoque
            WHERE OLD.estoque.ID_PRODUTO = OLD.ID;

И тогда вместо этого я получаю эту ошибку:

ERROR 1054: 1054: Unknown column 'OLD.estoque.ID_PRODUTO' in 'where clause'
SQL Statement:
DELETE FROM `papelaria`.`produto` WHERE (`ID` = '6')

Что я пропускаю или делаю неправильно?

PS: нетуверен, стоит ли упоминать, но я довольно новичок в SQL и программировании в целом, поэтому я был бы признателен, если бы вы приняли это во внимание при ответе (для всех целей, просто предположим, что я ничего не знаю о ^^)

Заранее спасибо!

1 Ответ

1 голос
/ 11 июня 2019

Вы можете изменить свой FK на:

CONSTRAINT `fk_Estoque_Produto1`
    FOREIGN KEY (`ID_PRODUTO`) 
    REFERENCES `produto` (`ID`)
    ON DELETE CASCADE

Тогда вам больше не понадобится триггер перед удалением, поскольку записи в таблице estoque будут удалены автоматически.

Аналогично, добавление ON UPDATE CASCADE решит вашу «проблему обновления» в случае, если кто-то обновит запись PK.

Все еще не уверен, почему вы хотите иметь фиктивные записи в таблице estoque.

...