2011-05-09 36 views
9

Tengo tablas de remolque concept_access y concept_access_log. Quiero crear un disparador que funcione cada vez que se elimine algo de concept_access, compruebe si hay un registro similar en la tabla de registro y, en caso contrario, inserta uno nuevo antes de que se elimine de concept_access.SI NO EXISTE en el disparador

he modificado gatillo y ahora parece que esto:

DROP TRIGGER IF EXISTS before_delete_concept_access; 
DELIMITER // 
CREATE TRIGGER before_delete_concept_access 
    BEFORE DELETE ON `concept_access` FOR EACH ROW 
    BEGIN 
     IF (SELECT 1 FROM concept_access_log WHERE map=OLD.map 
          AND accesstype=OLD.accesstype AND startdate=OLD.startdate AND stopdate=OLD.stopdate) IS NULL THEN 
      INSERT INTO concept_access_log (map, accesstype, startdate, stopdate) 
      VALUES (OLD.map, OLD.accesstype, OLD.startdate, OLD.stopdate); 
     END IF; 
    END// 
DELIMITER ; 

datos de ejemplo en concept_access antes de eliminar:

map accesstype startdate stopdate 
1 public  NULL  NULL  
1 loggedin 2011-05-11 NULL  
1 friends  NULL  NULL  

tabla Registro ya tiene 2 primeras filas. Y son exactamente los mismos que en concept_access. Al eliminar primera fila de la tabla concept_access, consigo este registro en la tabla:

map accesstype startdate stopdate 
1 public  NULL  NULL  
1 loggedin 2011-05-11 NULL  
1 friends  NULL  NULL  
1 public  NULL  NULL  

Si bien se supone que no introduzca nada porque (1, público, null, null) ya existe allí.

Esta tabla no tiene clave principal. No estaba creando estructura, así que no me preguntes por qué. Cambiarlo arruinará muchas funcionalidades ya existentes. Solo necesito mantener el registro de lo que se eliminó de la tabla concept_access y almacenarlo en el registro sin duplicados.

Realmente agradecería, si alguien puede descubrir lo que está pasando mal.

+0

OK, me di cuenta de cuál es el problema es, pero todavía no puede encontrar la solución adecuada. Algunos campos pueden ser NULL y, en caso de que el valor OLD sea igual a null, no funcionará algo como 'accesstype = OLD.accesstype'. Intenté cambiarlo a '(accesstype = OLD.accesstype O OLD.accesstype IS NULL)', pero aún no tuve suerte ... – Jull

+0

¿Puede mostrarnos también el trigger modificado completo, así como los datos de muestra en "concept_access"? y los registros en la tabla de registro antes y después de eliminar? – pilcrow

+0

@pilcrow: las actualizaciones están en el cuerpo de la pregunta – Jull

Respuesta

13
DROP TRIGGER IF EXISTS before_delete_concept_access; 
DELIMITER // 
CREATE TRIGGER before_delete_concept_access 
    BEFORE DELETE ON `concept_access` FOR EACH ROW 
    BEGIN 
     IF (SELECT COUNT(*) FROM concept_access_log WHERE map=OLD.map 
          AND accesstype=OLD.accesstype AND startdate=OLD.startdate AND stopdate=OLD.stopdate) = 0 THEN 
      INSERT INTO concept_access_log (map, accesstype, startdate, stopdate) 
      VALUES (OLD.map, OLD.accesstype, OLD.startdate, OLD.stopdate); 
     END IF; 
    END// 
DELIMITER ; 

No estoy usando no existe, simplemente probar si el partido recuento mayor que 0

su código funciona bien en mi matchine, ¿cuál es su versión de MySQL?

mysql> select version(); 
+------------+ 
| version() | 
+------------+ 
| 5.1.56-log | 
+------------+ 
1 row in set (0.00 sec) 
+0

versión 5.1.54-1ubuntu4 – Jull

+0

¡Guau! ¡Ahora funciona! Muchas gracias! – Jull

+0

@Jull, ¿estás usando el disparador _exact_ que publicó Neo? En mi prueba, esta respuesta no maneja los NULL correctamente, tal como lo comentó en respuesta a su propia pregunta anterior ... – pilcrow

1

Modificar cada condición de la cláusula de la subconsulta DONDE para comprobar si el valor de equivalencia o ambos valores nulos:
(map = OLD.map OR COALESCE(map, OLD.map) IS NULL)
AND
(accesstype = OLD.accesstype OR COALESCE(accesstype, OLD.accesstype) IS NULL)
AND

así sucesivamente y así sucesivamente

+0

Creo que la segunda opción no funcionará. Descubrí que MySQL no ve los valores NULL como iguales. Por lo tanto, la restricción única no funcionará para las filas con valores NULL. [enlace] (http: // stackoverflow.com/questions/2520894/mysql-unique-clustered-constraint-not-constraining-as-expected) – Jull

+0

@Jull, derecha - respuesta de actualización. – pilcrow