Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Error al comparar campos Mysql

Estas en el tema de Error al comparar campos Mysql en el foro de Mysql en Foros del Web. Hola a todos. Estoy usando Mysql 5.0.51b-community-nt, y tengo un problema al realizar una consulta sobre una tabla. El ejemplo es el siguiente: Código: SELECT ...
  #1 (permalink)  
Antiguo 30/06/2009, 05:26
 
Fecha de Ingreso: junio-2009
Mensajes: 15
Antigüedad: 14 años, 10 meses
Puntos: 1
Error al comparar campos Mysql

Hola a todos.

Estoy usando Mysql 5.0.51b-community-nt, y tengo un problema al realizar una consulta sobre una tabla. El ejemplo es el siguiente:

Código:
SELECT id, nombre FROM nodo WHERE departamento ='aaaa' ORDER BY id
El problema es que la columna departamento es de tipo INT(11), y al compararla con cualquier cadena que no sea un número, me devuelve aquellos nodos cuyo departamento es 0, cuando no debería devolver nada ya que evidentemente 0 != 'aaaa'. Si alguno de ustedes sabe si esto se trata de algún error de Mysql o puede explicarme porque Mysql lo trata de esta manera le estaria muy agradecido.

Saludos,
Joan
  #2 (permalink)  
Antiguo 30/06/2009, 05:38
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Error al comparar campos Mysql

No es un error. La conversión implícita de una cadena de caracteres que contenga letras a un formato numérico da como resultado cero(0), por lo tanto en realidad, MySQL está comparando el contenido de `departamento` con el valor cero (0).
Tal vez lo estés pensando desde la óptica de programación de aplicaciones o bien desde otro DBMS.
En el caso de MySQL, realiza conversiones contextuales entre lso dos miembros de las comparaciones o de las asignaciones.
En MySQL tu puedes asignar perfectamente una cadena a un DATETIME, por ejemplo, mientras la cadena contenga una fecha válida por formato. Así también, cuando asignas a un numero una cadena, en tanto lo único que contenga la cadena sean numeros.

Si quieres comprobar lo que digo, ejecuta esto y mira los resultados:
Código sql:
Ver original
  1. SELECT CAST('' AS UNSIGNED INT);
Código sql:
Ver original
  1. SELECT CAST('cccc' AS UNSIGNED INT);
Código sql:
Ver original
  1. SELECT CAST('12' AS UNSIGNED INT);
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 30/06/2009, 08:24
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Error al comparar campos Mysql

Cita:
El problema es que la columna departamento es de tipo INT(11), y al compararla con cualquier cadena que no sea un número, me devuelve aquellos nodos cuyo departamento es 0
Creo que esto es parte del problema. El 0 en el ámbito numérico es en realidad un valor por defecto. No deberías asignarlo a ningún departamento, como pareces haber hecho. Si haces la conversión de una cadena de texto que no tenga forma de fecha, te saldrá NULL, y eso es lo que debería salir, pero si no se acepta NULL, el valor por defecto es el 0. Y ese nunca debería ser un valor asignado porque no estaría siendo un identificador único de ese departamento, al ser identificador de todos los que no tienen identificador. Se recomienda que nunca un foreign key sea NULL, y también debería recomendarse que tampoco lo fuera el 0. Y trataría de cambiar ese primary key 0 y foreign key 0 a otro número.
  #4 (permalink)  
Antiguo 30/06/2009, 09:47
 
Fecha de Ingreso: junio-2009
Mensajes: 15
Antigüedad: 14 años, 10 meses
Puntos: 1
Respuesta: Error al comparar campos Mysql

Gracias por las respuestas. Aunque no se trate de un error, me parece que no es la mejor manera de comparar las dos partes. Sería más lógico pasar el entero a cadena y comparar, que no la cadena a entero y comparar. no se si en el resto de SGBD's se realizará de la misma manera, pero desde luego no me parece una forma correcta de comparar un entero con una cadena.

Jurena sólo decirte que departamento no es ninguna clave ajena, es simplemente una columna a la que se le debe asignar un numero entero. Quizá en un futuro sea una clave ajena, y sea lo más lógico, pero eso ya se decidirá, porque los departamentos de momento no tienen ningún otro campo de interés, no tienen nombre ni nada ...

De todas formas, ¿hay alguna manera de forzar a Mysql a realizar la comparación de otra manera, ya sea en una consulta en concreto como ésta, o de manera global mediante alguna directiva?
  #5 (permalink)  
Antiguo 30/06/2009, 09:57
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Error al comparar campos Mysql

¿Cómo utilizas el MySQL?
¿Lo estás usando desde una aplicación o estás usando directamente el SQL en alguna interfase?
Eso puede hacer la diferencia en las sugerencias y soluciones posibles.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 30/06/2009, 09:58
 
Fecha de Ingreso: junio-2009
Mensajes: 15
Antigüedad: 14 años, 10 meses
Puntos: 1
Respuesta: Error al comparar campos Mysql

Tengo una aplicación en PHP que se conecta a una BD Mysql.
  #7 (permalink)  
Antiguo 30/06/2009, 10:21
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Error al comparar campos Mysql

En ese punto lo más conveniente es restringir el ingreso de los valores a nivel aplicación. Es mucho más simple resolverlo de esa forma que quitarle flexibilidad a los motores de bases de datos.
Esto es: Si ese campo sólo va a tener números, entonces lo mejor es hacer que la aplicación sólo manipule números para esas consultas.
Para los programadores el criterio de flexibilidad que se aplica en los motores de bases de datos es un poco difícil de comprender, pero la idea central es que una base de datos debe responder consultas, no hacer validaciones que se trabajan en un nivel más alto; es por eso que el DBMS tolera ciertas cosas en pos de no impedir la ejecución de sentencias que son contextualmente válidas, aunque no estén redactadas con la precisión esperable.
Las validaciones de tipos de dato operan, en la base, no a nivel de datos entrantes, sino internamente: parámetros a stored procedures, triggers, functions, tablas, joins, índices, etc.
Para la validación de los datos enviados a las bases, están los conectores (.Net, java, etc), los que operan en la aplicación. A nivel de datos entrantes, lo que importa es la flexibilidad.

En resumen: Lo que debes tratar es de validar los datos ANTES de enviarlos a la base, ya que los DBMS están optimizados para consultas, no para reemplazar las capacidades de los lenguajes de programación.

Sugerencias:
Si vas a comparar datos numéricos con campos numéricos, no pongas los valores numéricos entre comillas. De esa forma si lo que entra es una cadena de caracteres sí se producirá un error. Esto:
Código sql:
Ver original
  1. SELECT id, nombre FROM nodo WHERE departamento =aaaa ORDER BY id
te hubiese devuelto un error por campo no encontrado, en lugar de ejecutarse con corrección.
En su lugar, debería ir algo así:
Código sql:
Ver original
  1. SELECT id, nombre FROM nodo WHERE departamento = 3 ORDER BY id

Que te devolvería un registro vacío si no existe el id=3.

Otro tip: Las fechas van en el formato 'yyyy-MM-dd', porque ese es el formato ANSI, si las quieres usar de otro modo hay que apelar a las funciones de fecha y hora de MySQL.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 30/06/2009, 12:09
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Error al comparar campos Mysql

Como sugerencia, se podría hacer la búsqueda con LIKE, lo que no deja de ser una conversión a string.
SELECT id, nombre FROM nodo WHERE departamento LIKE 'aaaa' ORDER BY id

naturalmente, también sirve para los números entendidos como cadena.
SELECT id, nombre FROM nodo WHERE departamento LIKE '2' ORDER BY id

Será menos eficiente, pero evita parte del problema, pues con 'aaaa' ya no encontrará el 0, con LIKE '0' sí y con LIKE 'cualquiernumero' también.
  #9 (permalink)  
Antiguo 30/06/2009, 12:26
 
Fecha de Ingreso: junio-2009
Mensajes: 15
Antigüedad: 14 años, 10 meses
Puntos: 1
Respuesta: Error al comparar campos Mysql

Gracias a los dos. Creo que voy a optar por comprobar si departamento es un numero, de no ser así imprimiré directamente que no se han encontrado resultados en lugar de dejar que se produzca un error en la consulta, ya que prefiero manejar todos los casos posibles antes que mostrar el mensaje de error Mysql.

Gracias, me habéis ayudado mucho.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:31.