2011-09-29 11 views
10

He leído esto article pero parece que no funciona para eliminarlo. Tengo este error al tratado de crear un disparador:¿Cómo escribir un disparador para cancelar la eliminación en 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

NEW.nombre de campo existe cuando inserta o actualiza un registro; cuando borras nada, viene nuevo a la base de datos. El error es claro: no puede usar NEW.id porque NO está permitido en un desencadenador DELETE – Marco

+1

Según el artículo vinculado, la declaración seleccionada debe fallar: su instrucción de selección se lee como real y no como la opción 'seleccionar en el maniquí 'del artículo que está destinado a fallar. – miherrma

Respuesta

17

intentar algo como esto -

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

¡Simple y exactamente lo que quiero! Muchas gracias ! – JatSing

+1

MySQL ha agregado el comando SIGNAL para generar errores. Creo que fue agregado después de esta respuesta. Si alguien está interesado: http://dev.mysql.com/doc/refman/5.5/en/signal.html – cgTag

+0

Gran adición @MathewFoscarini, acabo de volver a responder la pregunta usando la respuesta de Devart y el comando SIGNAL que sugirió . – mathielo

2

Como dice el error: no hay una nueva variable de eliminación.

puede usar new.id solo en insertar y actualizar. Use old.id en su lugar.

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

Bueno, los mensajes de error que dice con toda claridad: en un desencadenador DELETE no hay nueva.

  • En un desencadenador de inserción se puede acceder a los nuevos valores con NUEVO ..
  • En un desencadenador UPDATE se puede acceder a los nuevos valores con NUEVO, los viejos con -. Usted lo adivinó - VIEJO.
  • En un disparador Borrar puede acces los valores antiguos con VIEJO ..

Simplemente no tiene sentido tener NUEVO en un DELETE, al igual que de antiguo en un INSERT no tiene sentido.

12

Mejorar @ respuesta de Devart (aceptado) por @ comentario de MathewFoscarini sobre MySQL SIGNAL Command, en lugar de elevar un error llamando a un procedimiento inexistente que podría indicar su mensaje de error personalizado.

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 ; 

El SQLSTATE 45000 fue elegido como MySQL's Reference Manual sugiere:

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

De esta manera su mensaje personalizado se mostrará al usuario cada vez que se intenta eliminar registros de identificación de 1 o 2. Además, si no se deben eliminar registros de la tabla, puede eliminar las líneas IF .. THEN y END IF;. Esto evitaría que se borren ANY registros en la tabla.

Cuestiones relacionadas