PDA

Ver la Versión Completa : leer csv


aprendiz_delphi
18-03-2020, 12:03:51
Buenos dias.
Estoy empezando con esto del delphi.
Me planteo leer un fichero csv y tengo que pasarlo a una tabla de una base de datos.
Hay alguna opción en delphi para no hacerlo que simplifique la lectura y la concatenacion para realizar el insert.

CAMPO1;CAMPO2;CAMPO3
A;B;C
D;E;F
A;F;B

Necesitaria realizar 3 insert con esos 3 campos

Casimiro Notevi
18-03-2020, 12:48:06
¿Qué base de datos?

aprendiz_delphi
18-03-2020, 12:58:30
pues Maria_db, pero al final entiendo que esto es independiente.
Necesito crear los insert en el programa.

Neftali [Germán.Estévez]
18-03-2020, 13:12:28
Aquí tienes un par de links correspondientes a entradas del blog sobre leer un TXT (que puede ser un CSV) utilizando ADO.
Puedes pasarlo desde el fichero a un Dataset o directamente a la tabla.

https://neftali.clubdelphi.com/cargar-datos-de-un-txt-a-una-tdataset-utilizando-ado/
https://neftali.clubdelphi.com/cargar-datos-de-un-txt-a-un-tdataset-utilizando-ado-parte-2/

ecfisa
18-03-2020, 13:44:53
Hola.

Tenes que leer el archivo csv en un TStringList y sabiendo que la primer linea corresponde a la cabecera de columnas, operar en consecuencia.

Ejemplo simplificado usando la tabla Customers.csv (que viene con Delphi)

...
var
T1,T2: TStrings;
i,j: Integer;
begin
T1 := TStringList.Create;
try
T1.LoadFromFile('Customers.csv');
for i := 1 to T1.Count-1 do
begin
T2 := TStringList.Create;
ExtractStrings([';'], [' '], PChar(T1[i]), T2);
try
DataSet.Insert;
for j := 0 to DataSet.FieldCount-1 do
DataSet.Fields[j].AsString := StringReplace(T2[j],'"','',[rfReplaceAll]);
DataSet.Post;
finally
T2.Free;
end;
end;
finally
T1.Free;
end;
end;


Saludos :)

aprendiz_delphi
18-03-2020, 14:14:33
Gracias, por las ideas.
No puedo usar un dataset, ya que algunas veces, la insercion es incremental o completa en funcion del radio button.
lo primero que hago ya, es una select a la tablas para ver el nombre de las columnas y preparar los campos del insert.
Luego voy a leer linea a linea el fichero.
Cuando tenga la linea lo pasare a un tstringlist con el delimitador, para que me lo trocee.
Ahi generare el insert a la tabla, para luego pasarlo como un script.
Como lo veis?

ecfisa
18-03-2020, 18:50:43
Hola.
Gracias, por las ideas.
No puedo usar un dataset, ...

Use un TDataSet para el ejemplo por que en tu consulta inicial indicabas:

...
Me planteo leer un fichero csv y tengo que pasarlo a una tabla de una base de datos.
Hay alguna opción en delphi para no hacerlo que simplifique la lectura y la concatenacion para realizar el insert.
...


Saludos :)

bucanero
19-03-2020, 10:06:39
Hola!!

En MySQL/Maria existe una función directa que importa un CSV a una tabla. Los parámetros cambian un poco de MySQL a Maria_DB pero básicamente el funcionamiento es similar, aquí tienes la documentación:
Maria_DB: https://mariadb.com/kb/en/columnstore-load-data-infile/
MySQL: https://dev.mysql.com/doc/refman/8.0/en/load-data.html

Los requisitos para poder utilizar esta función es tener creada una tabla con todos los campos que contiene el CSV (puede ser una tabla temporal) y tener el fichero CSV en una ruta accesible de forma local por el motor de BBDD.

La ventaja principal es la rapidez de la conversión de los datos.

Ejemplo de uso para un fichero llamado "csv_test.csv" con separador de ";" y guardado en la carpeta tmd del servidor


LOAD DATA INFILE '/tmp/csv_test.csv'
INTO TABLE data_tmp -- tabla en la que se inserta
FIELDS
TERMINATED BY ';' -- separador de campos
OPTIONALLY ENCLOSED BY '"' -- indica si lascadenas van envueltas entre dobles comillas
LINES
TERMINATED BY '\r\n' -- el separador de linea


En MySQL se pueden usar algunos comandos mas como establecer valores por defecto o modificar registros duplicados, etc pero Maria_db esta un poco mas limitado

Y una vez que ya tengas los datos importados en la tabla puedes operar perfectamente con comandos SQL

ariasdill
27-03-2020, 21:06:17
Disculpa, no estoy seguro si es correcto.
En la parte de variables defines T1 como Tstrings y en el cuerpo del programa la inicializas como TStringlist

Es eso correcto? o es un error de dedo?

ecfisa
27-03-2020, 23:42:37
Hola.
Disculpa, no estoy seguro si es correcto.
En la parte de variables defines T1 como Tstrings y en el cuerpo del programa la inicializas como TStringlist

Es eso correcto? o es un error de dedo?
Si, es correcto. Estoy aplicando polimorfismo, uso la clase base para los objetos que representan listas de cadenas en Delphi, pero no puedo instanciarla directamente por que contiene métodos abstractos.

Sin embargo, si necesitara algún método o atributo, como por ejemplo el método Sort, de la clase derivada TStringList, debería declarar la variable de este último tipo o no los tendría disponibles.

Saludos :)