2010-03-29 61 views
29

Tengo una tabla que contiene una url y una cadena que representan sus parámetros. El problema es que quiero una URL y una cadena de parámetros para ser 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 ser de longitud arbitraria (más de 800 bytes o más, que es la longitud máxima para una clave MySql, por lo que no puedo usar Unique (url, params) ya que arroja un error ...).Cómo cancelar la operación INSERT en el desencadenador MySql?

pensé acerca del uso de los disparadores para hacer esto, pero ¿cómo puedo lanzar una excepción/generará un error si el disparador descubre el inserto está a punto de insertar una entrada duplicada? Me imagino que me gustaría tener una MySqlException arrojada como lo hace MySql con claves duplicadas, etc. para poder verla en mi código C#.

Tengo dos piezas en el gatillo Necesito ayuda con: ... Disminuir la excepción de lanzamiento a C# ... ¿Cómo puedo lanzar una excepción, etc. a C#? ... Permitir inserción ... - ¿cómo puedo permitir la inserción si no hay una 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 
+0

de MySQL 5.5, posiblemente anterior, puede utilizar las señales, [véase mi respuesta aquí] [1] [1]: http://stackoverflow.com/questions/24/throw-error- in-mysql-trigger/7189396 # 7189396 – RuiDC

Respuesta

6

Si su definición de la tabla es para un valor NOT NULL, podría configurar NUEVO a NULL, que en la práctica no haría la inserción. Es posible que deba activar el modo sql estricto para que esto funcione correctamente.

67

me encontré con esto y aunque la solución funciona más tarde me encontré con lo que se siente a mí como una solución mejor. Sospecho que esta no era una opción cuando esta pregunta fue respondida originalmente.

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 maligno) que puede atrapar. Para obtener más información sobre esto, véase: http://dev.mysql.com/doc/refman/5.5/en/signal.html

espero que esto ayude a alguien más!

+2

Esto es realmente sorprendente. Trabajó para mi. – rishad2m8

+1

Gracias. Necesitaba tener una tabla e imponer rangos no superpuestos, y esto me permitió hacerlo. – Kickstart

+1

Esta debería ser la respuesta aceptada ... ¡VOTO POR ARRIBA! – smashing

Cuestiones relacionadas