Ir al contenido



Foto

Problema al guardar path en caracter "/"

path mysql mariadb delphi

  • Por favor identifícate para responder
9 respuestas en este tema

#1 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 141 mensajes
  • LocationMéxico

Escrito 22 mayo 2017 - 10:33

Estimados buenos dias ..

 

Me sucedió un detalle, he checado el foro y al menos no encontré solución o algo parecido, es lo siguiente..

 

Tengo una BD mysql (mariadb) y trato desde Delphi (D7) guardar a dirección de una imagen, hago lo siguiente:


delphi
  1. if SavePictureDialog1.Execute then
  2. begin
  3. try
  4. Edit1.Text := SavePictureDialog1.FileName;
  5. Image1.Picture.LoadFromFile(Edit1.Text);
  6. except
  7. end;
  8. end;

Con esto busco y cargo la imagen en un componente Timage.

 

Después intento guardar esta dirección que pude de la imagen (Edit1.text) guardarlo en la BD de esta forma...


delphi
  1. // guardo el path en varible y lo guardo en la BD
  2. VANUE:= SavePictureDialog1.FileName;
  3.  
  4. with DMod1.ADOQueryCtrlONT do
  5. begin
  6. SQL.Clear;
  7. SQL.Add('UPDATE ctrlont SET ');
  8. SQL.Add('IMG_ONT = "'+ Trim(VANUE) +'" ');
  9. SQL.Add(' WHERE FOLIO = ' + Trim(StaticText1.Caption));
  10. ExecSQL;
  11. end;

Y lo guarda bien en la Base de datos ... PERO ....

 

Al checar el campo guardado, este lo guardo sin las barras osea "/" por ejemplo:

 

En lugar de guadarlo como:

 

C:\REG\IMG\imagen.jpg

 

Lo guarda de esta forma:

 

C:REGIMGimagen.jpg

 

No aparece el caracter barra "/", el campo que uso en la BD es de tipo Varchar(255)

 

Gracias de antemano .. 


  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.260 mensajes
  • LocationArgentina

Escrito 22 mayo 2017 - 11:16

Umm. En principio no veo nada mal en el código. Ni debiera de haber problemas, salvo que pueda haber un efecto indeseado al momento de hacer Trim.

 

Antes de actualizar el campo, prueba en mostrar en un ShowMessage() el valor de la variable VANUE. Fíjate si están las barras.

Haz lo mismo pero esta vez mostrando el contenido de Trim(VANUE).

 

Recuerda que Trim() elimina los espacios, por lo que no es lo mismo un path que se llame "D:\Libros Diarios\"  que uno llamado "D:\LibrosDiarios\"

 

Por otro lado, estás haciendo uso innecesario de variables intermedias. El primer caso al usar el Edit1 para tener la ruta. Puedes directamente pasarle el valor del FileName que regresa el SaveDialog al TImage para abrir la imagen:


delphi
  1. Image.Picture.LoadFromFile(SaveDialog1.FileName);

Lo mismo sucede con la variable VANUE. Se puede obviar.

Ahora bien, tienes la posibilidad de disponer de una variable global si vas a necesitar leer constantemente el FileName del SaveDialog desde muchas partes. Y directamente cada vez que necesites lees y/o guardas en la variable global. Por ejemplo: una vez elegida la imagen, establecer el valor de la variable global y te queda disponible para que en cualquier otra parte la leas.

Es una sugerencia que te hago. Reduces la cantidad de variables, el código se vuelve más estable y fácil de leer, y de mantener. En ocasiones se vuelve un lio cuando uno dispone de N variables para guardar siempre lo mismo... que en un procedimiento la llama de una forma, y en otro de otra.

 

Saludos,


  • 0

#3 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 141 mensajes
  • LocationMéxico

Escrito 22 mayo 2017 - 11:33

Umm. En principio no veo nada mal en el código. Ni debiera de haber problemas, salvo que pueda haber un efecto indeseado al momento de hacer Trim.

 

Antes de actualizar el campo, prueba en mostrar en un ShowMessage() el valor de la variable VANUE. Fíjate si están las barras.

Haz lo mismo pero esta vez mostrando el contenido de Trim(VANUE).

 

 

 

 

Quité el parámetro TRIM, incluso use el showmessage en ese variable y lo muestra perfectamente con los caracteres, el path completo, pero al guardarlo no lo guarda tal cual, lo guarda sin las barras...


  • 0

#4 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 141 mensajes
  • LocationMéxico

Escrito 22 mayo 2017 - 12:20

intente hacerlo de esta forma, usando parámetros ..


delphi
  1. // guardo el path en varible y lo guardo en la BD
  2. VANUE:= SavePictureDialog1.FileName;
  3.  
  4. with DMod1.ADOQueryCtrlONT do
  5. begin
  6. SQL.Clear;
  7. SQL.Add('UPDATE ctrlont SET ');
  8. SQL.Add('IMG_ONT = :ruta ');
  9. SQL.Add(' WHERE FOLIO = ' + Trim(StaticText1.Caption));
  10. Parameters.ParamByName('ruta').Value:= VANUE;
  11. ExecSQL;
  12. end;

y SI se pudo guardar perfectamente la dirección con las diagonales ....

 

Pero hay un detalle, en modo (run desde delphi) al realizar eta acción, me envía un mensaje de ..

 

 

---------------------------

Debugger Exception Notification
---------------------------
Project CTRO.exe raised exception class EOleException with message 'Argumentos incorrectos, fuera del intervalo permitido o en conflicto con otros'. Process stopped. Use Step or Run to continue.
---------------------------
OK   Help   
---------------------------
 

 

Lo curioso que en si el sistema lo ejecuto desde el EXE que crea delphi, alli no me manda ningún mensaje como el anterior.

 


  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.260 mensajes
  • LocationArgentina

Escrito 22 mayo 2017 - 12:21

Es algo muy raro...

 

¿el código que tienes es tal cual el que expones? No tiene sentido que suceda eso viendo ese código. ¿Hay código extra que no hayas mostrado entre la sentencia de asignación del valor a VANUE y la instrucción UPDATE?

 

No se me ocurre que puede ser. Lo máximo que puedo sugerirte es que cambies la línea:


delphi
  1. SQL.Add('IMG_ONT = "'+ Trim(VANUE) +'" ');

Por esta otra:


php
  1. SQL.Add('IMG_ONT = ' + QuotedStr(IncludeTrailingPathDelimiter(VANUE)));

En lugar de jugar con poner las comillas a mano, se lo dejamos a la función QuotedStr que es la vía segura. De paso forzamos a que se incluyan la barra final con la función IncludeTrailingPathDelimiter(). En teoría, si se ha pasado correctamente el valor de FileName del SaveDialog a la variable, tenes una ruta válida. De todas formas deberías verificar la existiencia del archivo.

No estoy seguro si existe alguna función similar a IncludeTrailingPathDelimiter pero que coloque las barras intermedias de un directorio. Mi primera impresión es que no existe. Ni hay forma de determinar cuando debería colocar una barra y cuando no.

 

Saludos,


  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.260 mensajes
  • LocationArgentina

Escrito 22 mayo 2017 - 12:32

El uso de parámetros es lo más aconsejable.

Es la forma más limpia y segura de trabajar.

 

Sobre el error que te sale, no estoy completamente seguro a que puede deberse. Pero en lo primero que verificaría es que no existiera parámetros definidos en tiempo de diseño previamente. Es el principal motivo de sospecha. Suele presentarse esos tipos de errores cuando reusamos un componente para muchas cosas, o que justo estuviste probando y usando ese componente para otra operación y te ha quedado "sucio".

 

El Clear no siempre "limpia" todo lo que uno define en tiempo de diseño.

 

Ah, por cierto, en ADO debes definirle el DataType al parámetro PREVIAMENTE, antes de invocar a Value:


delphi
  1. Paramaters.ParamByName('ruta').DataType := fsString;
  2. Paramaters.ParamByName('ruta').Value := VANUE;

Asi es como funciona ADO. De otra forma es proclive a problemas.

 

Saludos,


  • 1

#7 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 141 mensajes
  • LocationMéxico

Escrito 22 mayo 2017 - 12:59

El uso de parámetros es lo más aconsejable.

Es la forma más limpia y segura de trabajar.

 

Sobre el error que te sale, no estoy completamente seguro a que puede deberse. Pero en lo primero que verificaría es que no existiera parámetros definidos en tiempo de diseño previamente. Es el principal motivo de sospecha. Suele presentarse esos tipos de errores cuando reusamos un componente para muchas cosas, o que justo estuviste probando y usando ese componente para otra operación y te ha quedado "sucio".

 

El Clear no siempre "limpia" todo lo que uno define en tiempo de diseño.

 

 

 

Efectivamente el componente ADOQuery lo reutilizo muchas veces tanto para consultas como para los módulos de alta,baja,etc.. todo el llamado desde el DataModule (Dmod1) en mi caso ...

 

Creo que es por eso que me sigue enviando ese mensaje, aunque ya la ruta lo guarda en la Base de Datos correctamente.

 

por esta parte usar los parámetros quedó solucionado la pregunta principal del tema ..


php
  1. // guardo el path en variable y lo guardo en la BD
  2. VANUE:= SavePictureDialog1.FileName;
  3.  
  4. with DMod1.ADOQueryCtrlONT do
  5. begin
  6. SQL.Clear;
  7. SQL.Add('UPDATE ctrlont SET ');
  8. SQL.Add('IMG_ONT = :ruta ');
  9. SQL.Add(' WHERE FOLIO = ' + Trim(StaticText1.Caption));
  10. Parameters.ParamByName('ruta').DataType:= ftString;
  11. Parameters.ParamByName('ruta').Value:= VANUE;
  12. ExecSQL;
  13. end;

 

Ah, por cierto, en ADO debes definirle el DataType al parámetro PREVIAMENTE, antes de invocar a Value:

Paramaters.ParamByName('ruta').DataType := fsString;
Paramaters.ParamByName('ruta').Value := VANUE;

Asi es como funciona ADO. De otra forma es proclive a problemas.

 

 

Efectivamente lo que comentas, ya lo agregué, gracias por la observación ...


  • 0

#8 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 517 mensajes
  • LocationCali, Colombia

Escrito 30 mayo 2017 - 10:32

Hola, hasta donde puedo ver el caracter slash (/) es un caracter de escape, por lo tanto debes reemplazarlo por doble slash // para que no tengas problemas.

 

Ruta := StringReplace(Ruta,'/','//',[srall]);   //esto o algo similar para cambiar los slash simples.

 

Saludos.


  • 1

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.260 mensajes
  • LocationArgentina

Escrito 30 mayo 2017 - 01:04

Hola, hasta donde puedo ver el caracter slash (/) es un caracter de escape, por lo tanto debes reemplazarlo por doble slash // para que no tengas problemas.

 

Ruta := StringReplace(Ruta,'/','//',[srall]);   //esto o algo similar para cambiar los slash simples.

 

Saludos.

 

Confundes el tipo de slash, pero es posible que estés en lo cierto sobre que se trate de un carácter de escape.

Acabo de consultar y MySQL utiliza el backslash (\) como escape. Aquí hay algo de info al respecto.

Una posibilidad es reemplazar el backslash por doblebackslash (\\) para que al momento de insertar el texto tome efectivamente las barras. O bien, habilitar el modo NO_BACKSLASH_SCAPES.

 

Saludos,


  • 0

#10 genriquez

genriquez

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 517 mensajes
  • LocationCali, Colombia

Escrito 30 mayo 2017 - 01:55

Confundes el tipo de slash, pero es posible que estés en lo cierto sobre que se trate de un carácter de escape.

Acabo de consultar y MySQL utiliza el backslash (\) como escape. Aquí hay algo de info al respecto.

Una posibilidad es reemplazar el backslash por doblebackslash (\\) para que al momento de insertar el texto tome efectivamente las barras. O bien, habilitar el modo NO_BACKSLASH_SCAPES.

 

Saludos,

 

como dice el chavo, eso, eso eso....,  ;)


  • 0





Etiquetado también con una o más de estas palabras: path, mysql, mariadb, delphi