Archive for Junio, 2009

Miniacertijo en MySQL.

Martes, Junio 23rd, 2009

Esta mañana he estado un rato alucinando con unos resultados que me estaba dando el servidor de MySQL ante unas instrucciones de lo más simples cuyos resultados esperados eran a priori evidentes. Es probable que estuviera bajo los influjos de demasiado café, quién sabe, pero el caso es que durante unos buenos minutos no podía dar crédito a lo que estaba viendo. He aquí la secuencia de consultas llevadas a cabo:




mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
|       73 |
+----------+
1 row in set (0.00 sec)

mysql> update t set f = null;
Query OK, 73 rows affected (0.00 sec)
Rows matched: 73  Changed: 73  Warnings: 0

mysql> select count(*) from t where not isnull(f);
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)

Ahí al final, por supuesto, esperaba recibir un 0. Pero no...

He llegado a pensar que MySQL se había vuelto loco, que el servidor había cascado... qué se yo, tonterías. Al final he descubierto qué estaba pasando. ¿Alguien se anima a especular? De hecho con el nivelillo de algunos de los que a veces comentáis, estoy seguro que mientras leíais este post ya se os ha ocurrido qué estaba pasando, así que más que la solución, os propongo que comentéis cuánto rato os ha llevado dar con ella.

Resolución.

Pues el ganador por aproximación ha sido Pedro Cambra que ha comentado "que la tabla tenga algún tipo de clave foránea, un trigger o mucha actividad y según hayas hecho el update se hayan modificado datos". Efectivamente, en su día creé dos triggers sobre la tabla en cuestión, uno sobre inserciones (irrelevante en este caso) y otro para actualizaciones. Los dos hacían lo mismo: si al insertar o modificar un registro el campo g tenía un valor concreto 'x', el campo f tomaría otro valor concreto 'y' independientemente del que el usuario hubiera introducido. Esto estaba haciendo ahora que para 4 registros concretos (los que cumplián la condición para el campo g) el trigger impidiera que f tomara valor NULL para pasar a tomar el valor que en el trigger estaba previsto que tomara. Pero claro, había olvidado que esta tabla tenía estos triggers y de ahí vinieron esos minutos de incredulidad...