Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MySQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=21)
-   -   CSV con datos numericos con decimales. (https://www.clubdelphi.com/foros/showthread.php?t=95426)

Ariqueño 12-10-2021 23:34:10

CSV con datos numericos con decimales.
 
buenas comunidad.

tengo una tabla con un campo decimal (10,3) al pasar de un archivo csv a mysql con el comando sql "LOAD DATA INFILE" me trunca los decimales.
campo en CSV = -1290,345
campo en la tabla = -1290.000

pienso que la problemática esta en la coma en la CSV y el punto en el campo de la tabla .

hasta el momento no encontrado nada como para solucionar mi problema.

bucanero 13-10-2021 09:06:15

hola!!

Una forma de solucionar este problema es almacenar el valor en una variable temporal y establecer el valor correcto del campo en la sección SET del comando LOAD DATA aplicando una sustitución del separador decimal.

Aquí te dejo un ejemplo de como poder hacerlo:

Código SQL [-]
LOAD DATA INFILE 'C://xampp//tmp//tabla.csv'
INTO TABLE `tablacsv`
FIELDS TERMINATED BY ';' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
-- los valores correspondientes a los campos num1, num2, en vez de guardarlos
-- directamente en la BBDD se almacenan en las varibles temporales @num1, @num2
(`id`, `asunto`, @num1, @num2)
-- y en la seccion SET puedes establecer los valores de los campos aplicando los cambios que se deseen
-- en este caso se sustituye la coma decimal por punto
SET `num1`=CONVERT(replace(@num1, ',', '.'), decimal(10,3)),
    `num2`=CONVERT(replace(@num1, ',', '.'), decimal(10,3))

mRoman 13-10-2021 19:22:14

Cita:

Empezado por Ariqueño (Mensaje 543484)
buenas comunidad.

tengo una tabla con un campo decimal (10,3) al pasar de un archivo csv a mysql con el comando sql "LOAD DATA INFILE" me trunca los decimales.
campo en CSV = -1290,345
campo en la tabla = -1290.000

pienso que la problemática esta en la coma en la CSV y el punto en el campo de la tabla .

hasta el momento no encontrado nada como para solucionar mi problema.

Hola Ariqueño.

Usas Excel para tu archivo CSV??...ya que desde ahi lo puedes configurar para que elijas otro separador, por ejemplo pipe "|"...o cambiar la regionalización de tu S.O. (Windows)...ha de estar Español (España).

Saludos.

Ariqueño 14-10-2021 17:18:07

Cita:

Empezado por bucanero (Mensaje 543488)
hola!!

Una forma de solucionar este problema es almacenar el valor en una variable temporal y establecer el valor correcto del campo en la sección SET del comando LOAD DATA aplicando una sustitución del separador decimal.

Aquí te dejo un ejemplo de como poder hacerlo:

Código SQL [-]
LOAD DATA INFILE 'C://xampp//tmp//tabla.csv'
INTO TABLE `tablacsv`
FIELDS TERMINATED BY ';' ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
-- los valores correspondientes a los campos num1, num2, en vez de guardarlos
-- directamente en la BBDD se almacenan en las varibles temporales @num1, @num2
(`id`, `asunto`, @num1, @num2)
-- y en la seccion SET puedes establecer los valores de los campos aplicando los cambios que se deseen
-- en este caso se sustituye la coma decimal por punto
SET `num1`=CONVERT(replace(@num1, ',', '.'), decimal(10,3)),
    `num2`=CONVERT(replace(@num1, ',', '.'), decimal(10,3))

buen dia bucabero.

Código Delphi [-]
    DM.miSQL.SQL.Add('LOAD DATA INFILE :P1');
    DM.miSQL.SQL.Add('INTO TABLE temporal_stock');
    DM.miSQL.SQL.Add('FIELDS TERMINATED BY ";"');
    DM.miSQL.SQL.Add('LINES TERMINATED BY "\r\n"');
    DM.miSQL.SQL.Add('IGNORE 1 LINES');
    DM.miSQL.SQL.Add('(id_prod,nombre,@num1)');
    DM.miSQL.SQL.Add('set final_sala=CONVERT(REPLACE(@num1,",","."),decimal(12,3) '); // problema
    DM.miSQL.ParamByName('P1').Value := edit2.Text;
    DM.miSQL.ExecSQL;

tengo un error de sentencia SQL no puedo usar cremillas simple por ser caracteres reservados del delphi.
como puedo pasar ese error? gracias ..

bucanero 14-10-2021 17:33:14

Cita:

Empezado por Ariqueño (Mensaje 543519)
buen dia bucabero.

Código Delphi [-]
    DM.miSQL.SQL.Add('LOAD DATA INFILE :P1');
    DM.miSQL.SQL.Add('INTO TABLE temporal_stock');
    DM.miSQL.SQL.Add('FIELDS TERMINATED BY ";"');
    DM.miSQL.SQL.Add('LINES TERMINATED BY "\r\n"');
    DM.miSQL.SQL.Add('IGNORE 1 LINES');
    DM.miSQL.SQL.Add('(id_prod,nombre,@num1)');
    DM.miSQL.SQL.Add('set final_sala=CONVERT(REPLACE(@num1,",","."),decimal(12,3) '); // problema
    DM.miSQL.ParamByName('P1').Value := edit2.Text;
    DM.miSQL.ExecSQL;

tengo un error de sentencia SQL no puedo usar cremillas simple por ser caracteres reservados del delphi.
como puedo pasar ese error? gracias ..

Hola!!

MySQL no diferencia entre comillas simples y comillas dobles, por lo que puedes usar indistintamente unas u otras.

Para usar en delphi las comillas simples dentro de una cadena entrecomillada, se hace poniendo dos veces la comilla simple por ejemplo

Código Delphi [-]
   DM.miSQL.SQL.Add('set final_sala=CONVERT(REPLACE(@num1, '','', ''.''),decimal(12,3) '); // problema


Por otra parte MySQL te dará error en esta línea
Código SQL [-]
    DM.miSQL.SQL.Add('LOAD DATA INFILE :P1');
puesto que la sentencia LOAD DATA INFILE es muy restrictiva y no acepta parámetros para el nombre del fichero ni integrarla en procedimiento y funciones almacenadas en la BBDD. Por lo que tendrás que poner el nombre del fichero directamente desde delphi

Ariqueño 14-10-2021 19:23:41

Cita:

Empezado por bucanero (Mensaje 543520)
Hola!!

MySQL no diferencia entre comillas simples y comillas dobles, por lo que puedes usar indistintamente unas u otras.

Para usar en delphi las comillas simples dentro de una cadena entrecomillada, se hace poniendo dos veces la comilla simple por ejemplo

Código Delphi [-]
   DM.miSQL.SQL.Add('set final_sala=CONVERT(REPLACE(@num1, '','', ''.''),decimal(12,3) '); // problema


Por otra parte MySQL te dará error en esta línea
Código SQL [-]
    DM.miSQL.SQL.Add('LOAD DATA INFILE :P1');
puesto que la sentencia LOAD DATA INFILE es muy restrictiva y no acepta parámetros para el nombre del fichero ni integrarla en procedimiento y funciones almacenadas en la BBDD. Por lo que tendrás que poner el nombre del fichero directamente desde delphi

Código Delphi [-]
  DM.miSQL.SQL.Add('LOAD DATA INFILE :P1');
no eh tenido ningún problema con ese parametro en esa línea, pero sigo con los problemas con las comillas.

bucanero 15-10-2021 09:24:10

Hola!!

yo he probado con este código y a mi me funciona perfectamente

Código SQL [-]
  ZQuery1.SQL.Add('LOAD DATA LOCAL INFILE :P1');
  ZQuery1.SQL.Add('INTO TABLE `tablacsv`');
  ZQuery1.SQL.Add('FIELDS TERMINATED BY ";" ENCLOSED BY ''"'' ');
  ZQuery1.SQL.Add('LINES TERMINATED BY "\r\n"');
  ZQuery1.SQL.Add('IGNORE 1 LINES');
  ZQuery1.SQL.Add('(`id`, `asunto`, @num1, @num2)');
  ZQuery1.SQL.Add('SET `num1`=CONVERT(replace(@num1, ",", "."), decimal(10,3)), ');
  ZQuery1.SQL.Add('    `num2`=CONVERT(replace(@num2, '','', ''.''), decimal(10,3))');

  ZQuery1.ParamByName('P1').Value := Edit1.text;
  ZQuery1.ExecSQL;

como se aprecia en el código la línea de num1, usa las dobles comillas y para la línea de num2 las comillas simples. Por lo que las comillas no creo que sean el problema, pues se puede usar unas u otras independientemente

En cuanto a lo del parámetro P1 a mi también me ha funcionado usándolo desde el componente de QUERY de DELPHI :-).

Para poder ayudarte mas, indica el error exacto que obtienes

bucanero 15-10-2021 09:31:22

Cita:

Empezado por Ariqueño (Mensaje 543519)
buen dia bucabero.

Código Delphi [-]
    ...
    DM.miSQL.SQL.Add('set final_sala=CONVERT(REPLACE(@num1,",","."),decimal(12,3) '); // problema
    ...

tengo un error de sentencia SQL no puedo usar cremillas simple por ser caracteres reservados del delphi.
como puedo pasar ese error? gracias ..

Revisando mas a fondo tu código en esa línea te falta el cierre de paréntesis de la función CONVERT()

Código Delphi [-]
DM.miSQL.SQL.Add('set final_sala=CONVERT(REPLACE(@num1,",","."),decimal(12,3))');

comprueba si puede ser ese el error

kuan-yiu 15-10-2021 10:42:41

Siempre que necesites poner comillas en medio de un string que pases desde Delphi a SQL debes usar comillas dobles para que lo pase correctamente: "estoEsLoQuePasoEntrecomillado". No tiene tanto que ver con como maneja tu motor concreto de BD las comillas sino por como maneja Delphi los strings.
Yo normalmente para evitar líos con las comillas uso: QuotedStr(miVariableString). Esto me garantiza el uso de las comillas adecuadas en cada contexto porque uso distintos motores de BD.
Sino tan solo debes capturar la query que está enviando, justo antes del ExecSQL, y ver qué es lo que realmente ejecuta.


La franja horaria es GMT +2. Ahora son las 22:45:30.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi