Problema con consulta de access.

Alguien sabe por que en la siguiente consulta me da el error: No coinciden los datos en la expresión de criterios.
La consulta es esta:
SELECT *
FROM migra_cab_colegio
WHERE ref2<>""
and mid(ref2,len(ref2)-8,len(ref2))= mid(ref1,len(ref1)-8,len(ref1));
Tanto ref1 como ref2 son campos de tipo texto de 140 de longitud, y la expresión es correcta, ya que si pongo la siguiente select:
SELECT mid(ref2,len(ref2)-8,len(ref2))
FROM migra_cab_colegio
WHERE ref2<>"";
No me da ningún error.

1 respuesta

Respuesta
1
Lo que te ocurre es lo siguiente: Cuando se ejecuta una sentencia SQL primero, internamente, se realiza la selección de registros de la clausula WHERE ¡COMPLETA! (Es decir, da igual el orden de los operandos de la clausula WHERE) y posteriormente se trata lo definido entre el SELECT y el WHERE para mostrar los campos. Teniendo esto en cuenta, anilizemos tus dos casos:
1º El caso 2 - El que no te da error.
Primero se seleccionan todos los registros cuyo campo ref2 no esté vacío y luego, una vez seleccionados para trabajar sólo con ellos, se realiza la extracción con el MID y se muestran los datos. CORRECTO.
2º El caso 1 - El del error.
Primero se ejecuta la clausula WHER ¡COMPLETA! (Insisto), es decir, se realiza la selección de los registros cuyo campo ref2 sea igual a "" al mismo tiempo que se comprueba la igualdad de ese registro con los MID...
¡Aquí tu problema!. Pongamos el caso de que tienes un registro en esa tabla con el campo ref2 ="". Ejecutamnos la sentencia y primero se realiza la selección de la clausula WHERE ¡COMPLETA! (Otra vez insisto), por lo que ademas de comprobarse que ese registro cumple o no con la clausula "ref2 <> ''" al mismo tiempo se comprueba si cumple o no "mid(ref2, len(ref2)-8, len(ref2))= mid(ref1, len(ref1)-8, len(ref1))", pero como este registro es "" no se puede hacer el MID... ERROR!
Como solucionarlo ¿? Debes hacer una consulta previa en la que la cluausla where sea ref <> "" para luego hacer una consulta del resultado de esta primera con los MID... Seria algo así:
"SELECT *
FROM
(SELECT * FROM migra_cab_colegio
WHERE ref2<>"")
WHERE
and mid(ref2,len(ref2)-8,len(ref2))= mid(ref1,len(ref1)-8,len(ref1));"
Ese es el problema que estas teniendo... De todos modos es más importante que entiendas el porqué (lo que he intentado explicarte) más que el que consigas solucionar el problema con este ejemplo...
Si tienes alguna duda o problema, o no entiendes algo, no dudes en contactar conmigo.
Un saludo y espero haberte podido ser de ayuda. Suerte en tu desarrollo!
Óscar L.M.V.
Ante todo, muchas gracias por tu extensa aclaración. Todo lo que me indicas no lo sabía y me puede venir muy bien para evitar futuros problemas.
Lo malo es que me sigue dando exactamente el mismo error haciéndolo como me indicas. Te comento una cosa que no se si será de ayuda, pero puede que te oriente algo más. Si la select que yo pongo es así "SELECT *
FROM migra_cab_colegio
WHERE ref2<>""
and mid(ref2,8,len(ref2))=mid(ref1,8,len(ref1))", me funciona sin problemas, aunque evidentemente no me sirve para lo que yo quiero. Es decir, el error se me produce en el momento en el que cambio el 8 (que me he inventado), por una función (len, instr), que es lo que realmente necesito. Ojala esto aclare algo más el tema.
De nuevo jodra!
¿Estas seguro de que la longitud de Ref2 es siempre mayor que 8? Si en algún caso no fuera así, ese seria tu problema, ya que al restar Len(ref2)-8 si da 0 o un número negativo causaría el error...
Para asegurarnos que no es eso, haz una criba previa en la sentencia que ete propuse:
"SELECT *
FROM
(SELECT * FROM migra_cab_colegio
WHERE ref2<>"" and len(ref2)>8)
WHERE
and mid(ref2,len(ref2)-8,len(ref2))= mid(ref1,len(ref1)-8,len(ref1));"
De esta forma nos aseguramos que sólo trata los registros cuyo campo ref2 sea diferente a "" y cuya longitud de datos sea superior a 8.
Pruébalo y me cuentas, ok ¿?. Por el error que te da y la forma en que indicas que funciona, ahí debe estar el problema. Esta claro que si con un numero en lugar de la resta len(ref2)-8 funciona perfectamente, lo que causa el error es concretamente esa resta y para que falle una resta en tu sentencia es porque esta dando como resultado 0 o menor a 0.
Espero que me comentes, pero fijo que ahí esta el problema...
Hola Oscar!
He probado la nueva opción que me comentas, y me da exactamente el mismo error. He probado también con esta select:
SELECT * FROM (SELECT * FROM migra_cab_colegio WHERE ref2<>"" and instr(ref2,"/")<>"" and ref1<>"")
WHERE mid(ref2,instr(ref2,"/"),len(ref2))=mid(ref1,instr(ref1,"/"),len(ref1));
Y esta tampoco funciona. Ya no se que más probar. Se te ocurre algo más. Muchas gracias.
Acabo de confirmar que lo que te puse
"SELECT *
FROM
(SELECT * FROM migra_cab_colegio
WHERE ref2<>"" and len(ref2)>8)
WHERE
and mid(ref2,len(ref2)-8,len(ref2))= mid(ref1,len(ref1)-8,len(ref1));"
No es del todo correcto... Lo siento... Con esto que te puse, en el caso de que ref2 sea Nulo la longitud no devuelve 0 sino nulo también, por lo que continua el error...
Prueba con esto:
"SELECT *
FROM
(SELECT * FROM migra_cab_colegio
WHERE ref2<>"" and
len(IIf(IsNull(Len([ref2])),0,Len([ref2]))
)>8)
WHERE
and mid(ref2,len(ref2)-8,len(ref2))= mid(ref1,len(ref1)-8,len(ref1));"
Ahora, en el caso en que ref2 sea nulo, con el IIF lo detectamos y hacemos la comparación con respecto a 8 en lugar de con Nulo con 0...
Prueba esto y dime que tal... Ahora si que deberíamos corregir el error...
Si con esto sigues teniendo problemas, haz esto otro:
- Crea una consulta con esta sentencia:
SELECT * FROM migra_cab_colegio
WHERE ref2<>"" and
Len(IIf(IsNull(Len([ref2])), 0, Len([ref2]))
)>8. Llamala, por ejemplo, consulta1
- Crea otra consulta, llamala consulta2, con lo siguiente:
SELECT *
FROM
Consulta1
WHERE
and mid(ref2,len(ref2)-8,len(ref2))= mid(ref1,len(ref1)-8,len(ref1));"
Si con esto tampoco te va, dímelo para suicidarnos juntos, ok ¿? je je je
No, en serio. Prueba estas dos cosillas y dime algo... Hasta que no demos con ello palabra que no te dejo colgado...
He probado las dos opciones y sigue sin funcionarme. No se si se te ocurre algo más, pero no lo entiendo. Dejando de lado las dos últimas que probamos, por que crees que esta no funciona:
SELECT * FROM
(SELECT * FROM migra_cab_colegio WHERE ref2<>"" and instr(ref2,"/")<>"" and ref1<>"" and instr(ref2,"/")<>"")
WHERE mid(ref2,instr(ref2,"/"),len(ref2))=mid(ref1,instr(ref1,"/"),len(ref1));
Quizas tengo algún problema de configuración de access, ya no se que pensar...
Nada, que la puñetera consulta se ha empeñado en dar guerra...
Ultima opción -> Si quieres y no tienes inconveniente hadme llegar la BBDD por correo y le hecho un vistazo para detectarte y detallarte el fallo y como corregirlo...
Si no, ya no se me ocurre nada más...
Si te parece buena idea dímelo y te indico la dirección a la que puedes enviármelo.
La BBDD original no te la puedo enviar, pero me he creado un juego de prueba de 5 registros que contemplan la gran mayoría de casos que tengo en la original. He probado las consultas en ella y me dan el mismo error. Si me pasas tu dirección te la envío ahora mismo.
Mejor, prefiero no "jugar" con datos que no me interesa conocer... ;-)
[email protected]
Te la acabo de mandar.
Espero tus noticias.
Ya está arreglado... No hay nada como tener la BBDD entre manos... ;-)
La sentencia que debes poner es la que ponías en tu primer mensaje, pero debes tener en cuenta (como ya te decía en anteriores mensajes) el control de los posibles Nulos...
En resumen, la sentencia es:
SELECT *
FROM migra_cab_colegio
WHERE (((migra_cab_colegio.REF2)<>"") AND ((IIf(IsNull([ref2]),"",Mid([ref2],Len([ref2])-8,Len([ref2]))))=IIf(IsNull([ref1]),"",Mid([ref1],Len([ref1])-8,Len([ref1])))));
La única diferencia con tu sentencia inicial es que yo, con esta, controlo si ref1 o ref2 son Nulos, para en el caso de que lo sean sustituir el valor NULL por "" para así poder utilizar las funciones de texto (len, mid, ...) que siendo NULL no podría utilizar ya que daría error... Este era tu caso -> Al no controlar el posible valor NULL de los registros (como el caso del campo ref2 del 2º registro del ejemplo que me mandaste) estabas intentando utilizar funciones de texto (len, mid, ...) con un ese dato NULL.
Lo primero que hay quehacer, como resumen, si vas a utilizar funciones de texto es asegurarnos o CONTROLAR (como en este caso) la existencia de campos que puedan no contener datos (NULL) y una vez confirmado o controlado (en este caso controlado al convertirlo internamente para trabajar como "") ya puedes hacer uso de estas funciones.
Bueno, espero que esto solucione todos tus problemas. Por favor dime algo, ok ¿?
Por cierto, ¿a qué se dedica tu empresa? Yo trabajo en una empresa de Servicios Informáticos aquí en Madrid, y por lo que veo la tuya también lo es, no ¿?. Si puedes y quieres, cuéntame algo sobre tu empresa... Nunca esta de más conocer "compañeros" por otros lares... je je je
Bueno Oscar, pues parece que finalmente lo has conseguido. Lo he probado y la consulta la lanza. Lo único es que me da un error pero es por un problema con la BBDD que tengo que reparar, y en cuanto lo haga seguro que funciona sin problemas.
En realidad mi empresa es una empresa de servicios, pero no informáticos, nos dedicamos a la Gestión Documental o de Archivo, lo que pasa que es muy frecuente tener que estar realizando pequeñas aplicaciones en access para los retiros de documentación de los clientes.
Bueno, muchísimas gracias por tu ayuda, me ha servido de mucho no solo para solucionar este problema sino para comprender un poco mejor como funciona access.
Un saludo y hasta que volvamos a vernos.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas