Visual Basic Foro

Programación => Bases de Datos => Mensaje iniciado por: LeandroA en Mayo 26, 2014, 12:45:02 am

Título: Solucion para a las dobles comillas o tildes
Publicado por: LeandroA en Mayo 26, 2014, 12:45:02 am
Hola, supongo que es un tema ya discutido, pero ahora me toca preguntarlo, cual creen que se la mejor forma de solucionar el problemas con las dobles comillas o tildes, cuando uno arma la consulta SQL puede utilizar las " o ' pero bien si el dato a ingresar tienen uno de estos caracteres te arruina la consulta, entonces como tratan estos errores ustedes?. remplazan algunos de estos por algún carácter especial?
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Jeronimo en Mayo 26, 2014, 08:30:21 am
Hola, Leandro.
Seguramente no te aporte nada con mi comentario, pero lo dejo igualmente.
Para mí la mejor manera es como sugerís, porque "escapando" las comillas no sé si puede traer problemas al cambiar de base de datos (no sé si todas tratan igual ese procedimiento). Por eso creo que cambiar las comillas dobles y las simples por caracteres especiales sería la mejor solución que se me ocurre. De todas maneras yo directamente impido que el usuario ingrese estos caracteres: * ' " / (lo filtro en el evento Keypress de la caja de texto). Aunque uso este procedimiento para el ingreso de nombres y apellidos, no es del todo de mi agrado porque hay algunos apellidos que pueden contener comillas simples. Pero ya tenía el código hecho así cuando lo advertí, así que no lo cambié de vago nomás.
Seguramente los que saben te sugerirán caminos más apropiados.
Saludos.

Jerónimo
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Mayo 26, 2014, 04:02:30 pm
Claro, depende del motor de base de datos.
Yo particularmente trabajo con SQL Server, me ha pasado que dentro del algun valor venga una comilla, o alguna coma (delimitador de campo, o parametro de un SP)  y "rompan" la sintax SQL.
Lo que hago dentro del VB es reemplazar los caracteres con un REPLACE, justo antes de ejecutar las instruccion SQL,
por ej las ' o '' las reemplazo por un ´ es como un acento.

sSQL = REPLACE(sSQL, "'" , "`")
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: raul338 en Mayo 27, 2014, 10:05:39 am
En realidad no se debería permitir ese tipo de caracteres en campos simples (nombres, etc) pero una forma de hacerlo bien y sin reinventar la rueda es utilizar procedimientos por parámetros:

Código: (SQL) [Seleccionar]
SELECT nombre, apellido, descripcion FROM personas WHERE descripcion LIKE @paramDescripcion
y luego desde donde lo llames (ado, php con extension mysqli, etc) le pasas algo similar

Código: [Seleccionar]
comando.parametros.add("@paramDescripcion", txtBusqueda.text)
y listo, el mismo motor de la BD se encarga de escaparlo y como debería estar probado no tendrías mucho drama ni consecuencias raras al probarlo ;)

Nota: Tanto la conexión, como los strings que pasas (utf desde vb) como la base de datos deben tener la misma codificación sino vas a tener símbolos raros al leer/guardar valores... Asegura eso y no tendrás problemas en nada
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Mayo 27, 2014, 10:24:39 am
Muy bueno Raul! Es verdad lo que comentas de usar un Command desde VB para ejecutar y pasar parámetros. Pero yo por vago  ;D, me da fiaca escribir el codigo de agregar cada parametro al command, armo un string concatenando todo y desp pasan estas cosas :)
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: LeandroA en Mayo 28, 2014, 11:16:57 pm
Hola chicos gracias por las respuestas, lo que explico Raul la verdad no lo entendi, por el momento opte hacer un simple remplece con un caracter especial
Código: [Seleccionar]
Replace$(Word, Chr$(39), Chr$(1))
y luego hago la inversa, no me parece una buena solución ya que si tuviera que mostrar muchos datos de una gran consulta al restaurar todas las " podría consumir algo de tiempo, pero bueno sale con fritas
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Mayo 29, 2014, 10:33:21 am
Hola Leandro, si reemplazas por el chr(96) ` o el chr(180) ´, creo que no tendrias que volver a reemplazar para mostrarlo, se visualizan "casi" como una comilla.

Lo que explica Raul es ejecutar las intrucciones usando un ADODB.COMMAND.
A un COMMAND le podes decir que tipo de intruccion va a ejecutar (Texto, storeprocedure ... ) y si es un storeprocedure que lleva parámetros, podes declarar estos parametros en el COMMAND, indicando que tipo de parametro es (numerico, texto, etc) y.... hasta podes declarar un parametro como OUT, para recibir el valor return de un storeprocedure.

Segun Raul esta forma es la correcta, ya que el motor recibe cada parametro como corresponde y no se "cortaria" la instruccion si tuviese una coma en el medio.

Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: E N T E R en Mayo 29, 2014, 11:09:58 am
Tendrian un ejemplo de como utilizar lo que comenta Raul yo siempre tuve tambien ese problema.

Yo solucionaba con esto del Replace tambien asi:

Código: (VB) [Seleccionar]
Public Function Reemplazar(ByVal StrCad As String) As String
    'CARACTERES NO ADMITIDOS POR WINDOWS =   \/:*?"<>|
    StrCad = Replace(StrCad, "\", "-")
    StrCad = Replace(StrCad, "/", "-")
    StrCad = Replace(StrCad, ":", "-")
    StrCad = Replace(StrCad, "*", "-")
    StrCad = Replace(StrCad, "<", "-")
    StrCad = Replace(StrCad, ">", "-")
    StrCad = Replace(StrCad, "|", "-")
    StrCad = Replace(StrCad, " ", "-")
    StrCad = Replace(StrCad, """", "-")
    Reemplazar = StrCad
End Function
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Mayo 29, 2014, 11:32:24 am
Hola copio una parte de codigo que tenia por ahi....
Fijense en CommandText se indica el sp que va a ejecutar,
 CommandType indica que es un SP,
luego se crean los parametros, cada parametro lleva el nombre del parametro, el tipo de dato,  si corresponde su longitud y por ultimo el valor del parametro.
Luego se ejecuta con Execute

Código: (VB) [Seleccionar]
       Set adoCmd = New ADODB.Command
        With adoCmd
            .ActiveConnection = modSQL_Cnn.cnn
            .CommandText = "update_zona_by_suc"
            .CommandType = adCmdStoredProc
           
            .Parameters.Append .CreateParameter("@Id_Suc", adInteger, adParamInput, , lId_Suc_Destino)
            .Parameters.Append .CreateParameter("@NumZona", adTinyInt, adParamInput, , xZona)
            .Parameters.Append .CreateParameter("@ZonaDesc", adVarChar, adParamInput, 50, rsTemp("ZonaDesc"))
            .Parameters.Append .CreateParameter("@Habilitada", adBoolean, adParamInput, , rsTemp("Habilitada"))
           
            .Execute iRec
           
        End With
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: raul338 en Mayo 30, 2014, 12:12:51 am
Esta lindo el código que tiro Waldo, aunque hay algo que quiero aclarar: No hace falta crear un procedimiento almacenado. Basta con poner la consulta como la que puse (así tal cual o como la que iría dentro del stored procedure).
Si creas un stored procedure ganas en rendimiento (porque la consulta ya esta precompilada) pero si la mandas en texto es lo mismo en terminos de "seguridad"

Ej
Código: (VB) [Seleccionar]
Set adoCmd = New ADODB.Command
With adoCmd
    .ActiveConnection = modSQL_Cnn.cnn
    .CommandText = "SELECT nombre, apellido, descripcion FROM personas WHERE nombre LIKE '%@nombre%'"
    .CommandType = adCmdText
   
    .Parameters.Append .CreateParameter("@nombre", adVarChar, adParamInput, 50, txtNombre.Text)
    .Execute iRec
End With

Ojo: Creo que Access es el único que no permite esto... pero no estoy seguro... Si permite llamadas a procedimientos almacenados con parametros
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Mayo 30, 2014, 10:56:27 am
Ah..mira vos, no sabia que se podia poner directamente un SELECT con parametros.
Lo que me molesta un poco, es tener que escribir todo ese rollo para cada consulta, me gustaria armar una rutinita para poder reutilizarla, pero no se me ocurre como standarizar el pase de los parametros, ya que son variables, y pueden ser de diferente tipo cada parametro.
Habia pensado pasar como parametro un Array o Coleccion de parametros. O tal vez lo mejor seria declarar el parametro de la rutina diractemente como objeto adodb.parameters, no se,  habria que estudiarlo un poco  ::)
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Mayo 30, 2014, 05:25:26 pm
Bueno, como no me queria quedar con la duda, probé de ejecutar un procedimiento, pasando un parametro varchar, conteniendo comillas simples y dobles, comas, etc
1er caso: Directamente con el connection.execute

    cnn.Execute "EXEC [sysLog_ADD] @Origen=1, @Tipo_Ev=1, @Descripcion='Hola '1234,456;789'""ABC"""

Resultado:
Error! sintaxis incorrecta cerca de 1234


2do caso: usando el command (como dice Raul) creando un parametro varchar, y pasando dentro del parametro el contenido con comillas.

 
Código: (VB) [Seleccionar]
   Dim cmd As ADODB.Command
   
    Set cmd = New ADODB.Command
    cmd.ActiveConnection = cnn
    cmd.CommandType = adCmdStoredProc
    cmd.CommandText = "sysLog_ADD"
    cmd.Parameters.Append cmd.CreateParameter("@Origen", adSmallInt, adParamInput, , 1)
    cmd.Parameters.Append cmd.CreateParameter("@Tipo_Ev", adSmallInt, adParamInput, , 1)
    cmd.Parameters.Append cmd.CreateParameter("@Descripcion", adVarChar, adParamInput, 50, "Hola '1234,456;789'""ABC""")
    cmd.Execute

Resultado: INSERT OK

Conclusion: despues de años de usar Ado y VB, me doy cuenta que siempre falta aprender algo  ;D
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: LeandroA en Junio 07, 2014, 06:07:23 pm
Hola la verdad muy lindo todo pero no se de que me hablan  :)
yo lo único que conozco es esta forma de insertar datos

Código: [Seleccionar]
sSQL = "INSERT INTO TitulosEnCola (Nombre, Interprete, Genero, Duracion, IdTerminal, IdCategoria, PathDeOrigen) VALUES " & _
    "('" & RW(sTitulo) & "','" & RW(sInterprete) & "','" & RW(sGenero) & "','" & nDuracion & "','" & CboTerminales.ItemData(CboTerminales.ListIndex) & "','" & CboCategorias.ItemData(CboCategorias.ListIndex) & "','" & RW(sFileName) & "')"

    cnnBD1.Execute sSQL, , adCmdText

donde
Código: [Seleccionar]
Public Function RW(Word As String) As String
    RW = Replace$(Word, Chr$(39), Chr$(1))
End Function

Public Function UW(Word As String) As String
    UW = Replace$(Word, Chr$(1), Chr$(39))
End Function

utlizo Access y Adob
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: SKL en Junio 10, 2014, 09:57:09 pm
Hola la verdad muy lindo todo pero no se de que me hablan  :)
yo lo único que conozco es esta forma de insertar datos

Código: [Seleccionar]
sSQL = "INSERT INTO TitulosEnCola (Nombre, Interprete, Genero, Duracion, IdTerminal, IdCategoria, PathDeOrigen) VALUES " & _
    "('" & RW(sTitulo) & "','" & RW(sInterprete) & "','" & RW(sGenero) & "','" & nDuracion & "','" & CboTerminales.ItemData(CboTerminales.ListIndex) & "','" & CboCategorias.ItemData(CboCategorias.ListIndex) & "','" & RW(sFileName) & "')"

    cnnBD1.Execute sSQL, , adCmdText

donde
Código: [Seleccionar]
Public Function RW(Word As String) As String
    RW = Replace$(Word, Chr$(39), Chr$(1))
End Function

Public Function UW(Word As String) As String
    UW = Replace$(Word, Chr$(1), Chr$(39))
End Function

utlizo Access y Adob


Para que reemplazas??? no hace falta... los Textos van con comilla simple, los numeros sin nada y las fechas con HASH #.... yo no reemplazo nada, le mando fruta asi nomas exactamente de la misma manera que vos... sacale la funcion de RW a todos y vas a ver que funciona igual... a menos que el string ya contenta comillas desde antes.... igual no tendria sentido
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Junio 11, 2014, 09:47:33 am
Para que reemplazas??? no hace falta... los Textos van con comilla simple, los numeros sin nada y las fechas con HASH #.... yo no reemplazo nada, le mando fruta asi nomas exactamente de la misma manera que vos... sacale la funcion de RW a todos y vas a ver que funciona igual... a menos que el string ya contenta comillas desde antes.... igual no tendria sentido

Fijate que pasa si uno de los datos string contiene una coma... el motor va a pensar que esa coma es la separacion de un campo y te va a dar error
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: wolf_kof en Junio 11, 2014, 11:45:51 am
Leandro te voy a explicar la sentencia de SQL para ingresar datos es esta

Código: (vb) [Seleccionar]
Dim sSQL As String
sSQL = "INSERT INTO Tabla (Campo1, Campo2, Campo3) VALUES ('Maria', 'Pedro', 'Juan')"

Y es literalmente lo que haces cuando construyes tu cadena de esta forma:

Código: (vb) [Seleccionar]
Dim sSQL As String
sSQL = "INSERT INTO Tabla (Campo1, Campo2, Campo3) VALUES ('"& text1.text &"', '"& text2.text &"', '"& text3.text &"')"

de estas dos formas si algunos de los campos text tiene una ' u otro campo, tendras problema por que lo estás trabajando todo a base de texto, por eso lo haces con el commandtext (Comando de Texto)

Mientras si creas un procedimiento almacenado en tu base de datos en este caso access, con una consulta de insersión creo que se llama

ya la cosa cambia por que lo que haces es hacer un enlace del procediiento almacenado dandole los datos y el procedimiento ingresa el registro

Como lo explica Waldo

Código: (vb) [Seleccionar]
       Dim cmd As ADODB.Command
       
        Set cmd = New ADODB.Command
        cmd.ActiveConnection = cnn
        cmd.CommandType = adCmdStoredProc 'Aqui le decimos al comando que vamos a enlazar un procedimiento almacenado
        cmd.CommandText = "sysLog_ADD" 'Aqui hacemos mensión de como se llama el procedimiento almacenado (nada mas el nombre)

        cmd.Parameters.Append cmd.CreateParameter("@Campo1", adVarChar, adParamInput, , 1, text1.text)
        cmd.Parameters.Append cmd.CreateParameter("@Campo2", adVarChar, adParamInput, , 1, text2.text)
        cmd.Parameters.Append cmd.CreateParameter("@Campo3", adVarChar, adParamInput, 50, text3.text)
cmd.Execute

De esta forma no importa que contenga el text1.text se va a guardar dentro del @Campo1 y este dentro del procedimiento a su vez lo va a guardar en Campo1 dentro de tu tablal.

Te dejo el link que aunque es con vb.net pero hay ves la forma de hacer procedimientos almacenados con access:

http://wilfredo-patricio.blogspot.com/2008/07/procedimientos-almacenados-en-access-y.html?showComment=1359210191451 (http://wilfredo-patricio.blogspot.com/2008/07/procedimientos-almacenados-en-access-y.html?showComment=1359210191451)

Y este para que aprendas de los procedimientos almacenados y como manipularlos desde vb6

http://many-how.com/articulos/computadoras/programacion-ordenadores/visual-basics/article-725.html (http://many-how.com/articulos/computadoras/programacion-ordenadores/visual-basics/article-725.html)
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: Waldo en Junio 13, 2014, 02:32:35 pm
una cosa que me pasó, no se si tiene mucho que ver con este tema, pero como justo hablamos de los parametros del command, lo comento...
Tengo una base SQL con un campo "real" (numeros decimales, similar a float) segun busque el "equivalente" en ADO, para declarar el parametro es adSingle, tenia que llamar a un proc que hacia un INSERT, lo hacia sin devolver error, pero cuando miraba el numero con decimales, insertado en la base, no se veia como tenia que verse, se veia con notacion cientifica, con exponencial, algo rarisimo.
Despues de dar muuuchas vueltas me doy cuenta que el numero que le estaba pasando desde el VB como parametro, era decimal, pero separado con un punto ( . ) y.... justamente mi config regional el punto es separador de miles, no separador decimal, el decimal es la coma, asi que ojo con eso!
Título: Re:Solucion para a las dobles comillas o tildes
Publicado por: LeandroA en Junio 14, 2014, 04:17:22 am
Ahora si muchos mas claro, todo nuevo para mi esto. gracias por la info, voy a ver si ya lo voy implementando.