2011-09-29 12 views
10

Przeczytałem to article, ale wygląda na to, że nie działa w przypadku usuwania. Dostałem ten błąd, gdy próbował stworzyć wyzwalacz:Jak napisać wyzwalacz, aby przerwać usuwanie w MYSQL?

Executing SQL script in server

ERROR: Error 1363: There is no NEW row in on DELETE trigger

CREATE TRIGGER DeviceCatalog_PreventDeletion 
BEFORE DELETE on DeviceCatalog 
FOR EACH ROW 
BEGIN 
    DECLARE dummy INT; 

    IF old.id = 1 or old.id =2 THEN 
     SELECT * FROM DeviceCatalog WHERE DeviceCatalog.id=NEW.id; 
    END IF; 
END; 

SQL script execution finished: statements: 4 succeeded, 1 failed

+0

Nazwa NEW.field istnieje po włożeniu lub aktualizacji rekordu; kiedy nic nie usuniesz, nowy nadchodzi do bazy danych !!! Błąd jest jasny: nie możesz użyć NEW.id, ponieważ NEW nie jest dozwolony w wyzwalaczu DELETE – Marco

+1

Zgodnie z połączonym artykułem wybrane ustawienie powinno się nie powieść - twoja instrukcja select czyta się jak prawdziwa, a nie jak "wybierz do manekina" 'z artykułu, który ma zawieść. – miherrma

Odpowiedz

17

Spróbuj coś takiego -

DELIMITER $$ 

CREATE TRIGGER trigger1 
BEFORE DELETE 
ON table1 
FOR EACH ROW 
BEGIN 
    IF OLD.id = 1 THEN -- Abort when trying to remove this record 
    CALL cannot_delete_error; -- raise an error to prevent deleting from the table 
    END IF; 
END 
$$ 

DELIMITER ; 
+0

Proste i dokładnie to, co chcę! Wielkie dzięki ! – JatSing

+1

MySQL dodał polecenie SIGNAL, aby podnieść błędy. Myślę, że został dodany po tej odpowiedzi. Jeśli ktoś jest zainteresowany: http://dev.mysql.com/doc/refman/5.5/en/signal.html – cgTag

+0

Świetny dodatek @MathewFoscarini, Właśnie odpowiedziałem na to pytanie, używając odpowiedzi Devarta i polecenia SIGNAL, które zasugerowałeś . – mathielo

2

Jak mówi o błędzie: Nie ma nową zmienną o usunięcie.

możesz użyć new.id tylko przy wstawianiu i aktualizacji. Zamiast tego użyj old.id.

SELECT * FROM DeviceCatalog WHERE DeviceCatalog.id=old.id; 
6

Cóż, komunikaty o błędach wyraźnie mówią: w wyzwalaczu DELETE nie ma NOWEGO.

  • W wyzwalacz INSERT można uzyskać dostęp do nowych wartości z nowymi ..
  • W wyzwalacza UPDATE można uzyskać dostęp do nowych wartości w nowe, stare z. - zgadliście - OLD.
  • W DELETE wyzwalacza można acces starych wartości ze starymi ..

To po prostu nie ma sensu, aby mieć nowe w DELETE, tak jak w starym INSERT nie ma sensu.

12

Poprawa @ (zaakceptowane) odpowiedź Devart jest z @ komentarzu MathewFoscarini za około MySQL SIGNAL Command, zamiast podnoszenia błąd przez wywołanie zerową procedurę można zasygnalizować swój niestandardowy komunikat o błędzie.

DELIMITER $$ 

CREATE TRIGGER DeviceCatalog_PreventDeletion 
BEFORE DELETE ON DeviceCatalog 
FOR EACH ROW 
BEGIN 

    IF old.id IN (1,2) THEN -- Will only abort deletion for specified IDs 
    SIGNAL SQLSTATE '45000' -- "unhandled user-defined exception" 
     -- Here comes your custom error message that will be returned by MySQL 
     SET MESSAGE_TEXT = 'This record is sacred! You are not allowed to remove it!!'; 
    END IF; 

END 
$$ 

DELIMITER ; 

SQLSTATE 45000 została wybrana jako MySQL's Reference Manual proponuje:

To signal a generic SQLSTATE value, use '45000', which means “unhandled user-defined exception.”

ten sposób własnych wiadomość będzie widoczna dla użytkownika, gdy próbuje usunąć rekordy ID 1 lub 2. Ponadto, jeśli żadne rekordy nie powinny zostać usunięte z tabeli, możesz po prostu usunąć linie IF .. THEN i END IF;. Zapobiegnie to usuwaniu rekordów z tabeli.

Powiązane problemy