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
User avatar
XeviCOMAS
Posts: 433
Joined: Sat Mar 12, 2011 8:16 pm

Consultas o busquedas TDataSet

Postby XeviCOMAS » Sat Apr 21, 2018 4:16 pm

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
Posts: 76
Joined: Wed Jun 16, 2010 2:33 pm

Re: Consultas o busquedas TDataSet

Postby Jose Lopez » Sun Apr 22, 2018 12:31 pm

Xevi,
Has probado esto: cCadenaBuscar := [Carte d'Or serie "XL"]
Saludos.
Pepe.
User avatar
jfgimenez
Site Admin
Posts: 5568
Joined: Mon Apr 06, 2015 8:48 pm
Contact:

Re: Consultas o busquedas TDataSet

Postby jfgimenez » Sun Apr 22, 2018 4:07 pm

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:

Code: Select all

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:

Code: Select all

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

Code: Select all

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
User avatar
XeviCOMAS
Posts: 433
Joined: Sat Mar 12, 2011 8:16 pm

Re: Consultas o busquedas TDataSet

Postby XeviCOMAS » Sun Apr 22, 2018 8:35 pm

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.
User avatar
XeviCOMAS
Posts: 433
Joined: Sat Mar 12, 2011 8:16 pm

Re: Consultas o busquedas TDataSet

Postby XeviCOMAS » Sun Apr 22, 2018 8:45 pm

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.

Return to “Spanish”