In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Consultas o busquedas TDataSet

Foro de Xailer profesional en español
Responder
Avatar de Usuario
XeviCOMAS
Mensajes: 582
Registrado: Sab Mar 12, 2011 8:16 pm

Consultas o busquedas TDataSet

Mensaje por XeviCOMAS »

Me encuentro con un problemón al buscar o filtar en DataSets MariaDB.

dado un TEdit... ::oEdit1:cText

Carta de Oro

y al realizar la búsqueda aproximada...
::oDSTable:Locate( "DESCRIPCIO >= '" + " '" +::oEdit1:cText+ "'",, .F. )
localiza el primer registro que empieza por el texto solicitado correctamente...

O un filtro...
::oDSTable:Filter( "DESCRIPCIO LIKE '%" + Upper(::oEdit1:cText) + "%'",, .F. )

***********
PERO...
si el contenido del ::oEdit1:cText

Carte D'Or

lanzo el mismo Locate y no funciona, se queja y me lanza error.
Es por la comilla simple que hay en cText del oEdit1.

Puedo "saltar" este inconveniente cambiando las comillas simples por dobles i las dobles por simples...
::oDSTable:Locate( 'DESCRIPCIO >= "' + ' "' +::oEdit1:cText+ '"',, .F. )
O un filtro...
::oDSTable:Filter( 'DESCRIPCIO LIKE "%' + Upper(::oEdit1:cText) + '%"',, .F. )

***********
PERO el tema se complica si el texto del oEdit1 contiene comillas simples y dobles conjuntamente.

Carte d'Or serie "XL"

Dado ese posible caso... como lo hago???
Como lo haceis???
Como aplicar correctamente el Locate o Filter en un DataSet MariaDB???


Gracias.
Un Saludo,
Xevi.
Jose Lopez
Mensajes: 123
Registrado: Mié Jun 16, 2010 2:33 pm

Re: Consultas o busquedas TDataSet

Mensaje por Jose Lopez »

Xevi,
Has probado esto: cCadenaBuscar := [Carte d'Or serie "XL"]
Saludos.
Pepe.
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5706
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Re: Consultas o busquedas TDataSet

Mensaje por jfgimenez »

Xevi,

debes utilizar el método :StrSql() del datasource. Ese método te devuelve la cadena "escapada" para usarla sin problemas en las sentencias. Échale un vistazo también al método :BuildSqlSt().

Por otro lado, NUNCA, NUNCA, NUNCA, se deben usar cadenas que teclee el usuario directamente en una sentencia SQL. P.ej., imagina una simple e inocente sentencia que obtiene el código de cliente buscandolo por su nombre:

Código: Seleccionar todo

cCodigo := oDB:QueryValue( "SELECT Codigo FROM Clientes WHERE Nombre='" + ::oEdit1:Value + "'" )
Sí, ya sé que debería haber usado el operador LIKE en vez de el igual, pero es sólo un ejemplo de lo que viene ahora.
Bien, hasta aquí todo normal, ¿no? Si un usuario escribe "JOSE" en el edit, la sentencia que se va a ejecutar sobre la base de datos es:

Código: Seleccionar todo

SELECT Codigo FROM Clientes WHERE Nombre='JOSE'
y devolverá el valor del campo Codigo si encuentra ese cliente, y si no, devolverá NULL (o Nil ya en PRG).

Pero ahora imagina que el usuario escribe " '; DROP TABLE Clientes; #". Pues ahora, lo que se estaría ejecutando es

Código: Seleccionar todo

SELECT Codigo FROM Clientes WHERE Nombre=''; DROP TABLE Clientes; #'
Resultado: se carga la tabla Clientes. Eso es lo que se llama "SQL injection" o "inyección de código SQL". Si utilizas :StrSql() o :BuildSqlSt() no tendrás ese problema.

Este ya es un clásico, pero para los que no lo hayan visto antes: http://xkcd.com/327
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
Avatar de Usuario
XeviCOMAS
Mensajes: 582
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Consultas o busquedas TDataSet

Mensaje por XeviCOMAS »

Jose,

GRACIAS!!!


Jod*rrrr!!!
Con la de vueltas que he lidiado con este temilla!!!
Un par de noches sin descansar, dandole vueltas, unas funcioncillas mias tirando de UniToU8()...

Function xDateSQL( c )
IF( ValType(c) = "D", c := DToC(c), )
RETURN Right(c,4) +"/"+ SubStr(c,4,2) +"/"+ Left(c,2)
***
Function xStrSQL( c )
c := StrTran( c, "²", "d" ) //No vol aquest caracter
c := UniToU8(c)
c := StrTran( c, "\", "\\" )
c := StrTran( c, "'", "\'" ) // Substitueixo el signe ' per \' ja que MariaDB l'utilitza de delimitador de camps
RETURN c
Function xStr2SQL( c )
c := StrTran( c, "\", "\\" )
c := StrTran( c, "'", "\'" ) // Substitueixo el signe ' per \' ja que MariaDB l'utilitza de delimitador de camps
RETURN c

y NO SE ME OCURRIÓ PROBAR CON LA FUNCION StrSQL() !!!

Muchas gracias por tus respuestas, siempre concisas y efectivas.
Un Saludo,
Xevi.
Avatar de Usuario
XeviCOMAS
Mensajes: 582
Registrado: Sab Mar 12, 2011 8:16 pm

Re: Consultas o busquedas TDataSet

Mensaje por XeviCOMAS »

Jose, el método :StrSql() en el datasource, no existe o no lo encuentro...

Lo estoy probando como función y parece funcionar bien...

::oDSTable:Locate( "DESCRIPCIO >= '" +StrSQL(::oEditRecerca:cText)+ "'",, .F. )
O
::oDSTable:Filter( "LOCATE ('"+ StrSQL(Upper(::oEditRecerca:cText)) +"', `DESCRIPCIO`)",, .F. )


Gracias.
Un Saludo,
Xevi.
Responder