¿Cómo cancelar la operación INSERT en el disparador MySql?

Resuelto johnrl asked hace 14 años • 3 respuestas

Tengo una tabla que contiene una URL y una cadena que representa sus parámetros. El problema es que quiero que una URL y una cadena de parámetros sean la restricción única para la tabla; es decir, ninguna entrada puede tener la misma URL Y cadena de parámetros. La cadena de parámetros puede tener una longitud arbitraria (más de 800 bytes aproximadamente, que es la longitud máxima para una clave MySql, por lo que no puedo usar Unique(url, params) ya que arroja un error...).

Pensé en usar disparadores para hacer esto, pero ¿cómo puedo generar una excepción o generar un error si el disparador descubre que la inserción está a punto de insertar una entrada duplicada? Me imagino que me gustaría que se lanzara una MySqlException como lo hace MySql con claves primarias duplicadas, etc. para poder detectarla en mi código C#.

Tengo dos partes en el disparador con las que necesito obtener ayuda: ... Anular el lanzamiento de una excepción a C#... ¿Cómo lanzo una excepción, etc. a C#? ... Permitir inserción... - ¿Cómo puedo permitir la inserción si no hay ninguna entrada duplicada?

Aquí está el código de activación:

CREATE TRIGGER urls_check_duplicates
BEFORE INSERT ON urls
FOR EACH ROW

BEGIN
DECLARE num_rows INTEGER;

SELECT COUNT(*)
INTO num_rows
FROM urls
WHERE url = NEW.url AND params = NEW.params;

IF num_rows > 0 THEN
   ... ABORT/throw exception to C# ...
ELSE
   ... Allow insert ...
END
johnrl avatar Mar 29 '10 21:03 johnrl
Aceptado

Me encontré con esto y, aunque la solución funciona, luego encontré lo que me parece una solución mejor. Sospecho que esta no era una opción cuando se respondió originalmente esta pregunta.

CREATE TRIGGER `TestTable_SomeTrigger`
BEFORE UPDATE ON `test_table`
FOR EACH ROW
BEGIN
    DECLARE msg VARCHAR(255);
    IF (SomeTestToFail = "FAIL!") THEN
        set msg = "DIE: You broke the rules... I will now Smite you, hold still...";
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
    END IF;

    -- Do any other code here you may want to occur if it's all OK or leave blank it will be
    --  skipped if the above if is true
END$$

Esto ahora devolverá un mensaje de error agradable (¡o malvado!) que puedes atrapar. Para obtener más información sobre esto, consulte: http://dev.mysql.com/doc/refman/5.5/en/signal.html

¡Espero que esto ayude a alguien más!

GazB avatar Dec 19 '2011 09:12 GazB

Los comentarios en la documentación de MySQL sobre activadores sugieren que no existe tal característica en MySQL. Lo mejor que puede hacer es crear una tabla separada para los errores de activación, como se sugiere en la misma página .

soulmerge avatar Mar 29 '2010 14:03 soulmerge