Generar sentencias SQL de inserción desde un archivo CSV
Pregunta
Necesito importar un archivo csv a pájaro de fuego y pasé un par de horas probando algunas herramientas y ninguna se ajusta a mis necesidades.
El principal problema es que todas las herramientas que he estado probando como Importación de datos EMS y Asistente de datos de Firebird Espero que mi archivo CSV contenga toda la información que necesita mi tabla.
Necesito escribir algo de SQL personalizado en la instrucción de inserción, por ejemplo, tengo un archivo CSV con el nombre de la ciudad, pero como mi base de datos ya tiene todas las ciudades en otra tabla (normalizada), necesito escribir una subselección en la inserción declaración para buscar la ciudad y escribir su ID, también tengo un procedimiento almacenado para crear GUIDS.
Mi declaración de inserción sería algo como esto:
INSERT INTO PERSON (ID, NAME, CITY_ID) VALUES((SELECT NEW_GUID FROM CREATE_GUID), :NAME, (SELECT CITY_ID FROM CITY WHERE NAME = :CITY_NAME)
¿Cómo puedo abordar esto?
Solución
Es un poco tosco, pero para trabajos puntuales, a veces uso Excel.
Si importa el archivo CSV a Excel, puede crear una fórmula que cree una instrucción INSERT mediante el uso de concatenación de cadenas en la fórmula.Entonces, si su archivo CSV tiene 3 columnas que aparecen en las columnas A, B y C en Excel, podría escribir una fórmula como...
="INSERT INTO MyTable (Col1, Col2, Col3) VALUES (" & A1 & ", " & B1 & ", " & C1 & ")"
Luego, puede replicar la fórmula en todas sus filas y copiar y pegar la respuesta en un archivo de texto para ejecutarla en su base de datos.
Como digo, es tosco, ¡pero puede ser una forma bastante "rápida y sucia" de hacer un trabajo!
Otros consejos
Bueno, si es un CSV y es un proceso único, abra el archivo en Excel y luego escriba fórmulas para completar sus datos de la manera que desee, y luego escriba una fórmula Concat simple para construir su SQL, y luego copie esa fórmula para cada fila.Obtendrá una gran cantidad de declaraciones SQL que podrá ejecutar en cualquier lugar que desee.
fabio,
He hecho lo que Vaibhav ha hecho muchas veces y es una buena forma "rápida y sucia" de introducir datos en una base de datos.
Si necesita hacer esto varias veces, o según algún tipo de programación, entonces una forma más confiable es cargar los datos CSV "tal cual" en una tabla de trabajo (es decir, customer_dataload) y luego usar declaraciones SQL estándar para completar el campos faltantes.
(No conozco la sintaxis de Firebird, pero es algo como...)
UPDATE person
SET id = (SELECT newguid() FROM createguid)
UPDATE person
SET cityid = (SELECT cityid FROM cities WHERE person.cityname = cities.cityname)
etc.
Por lo general, es mucho más rápido (y más confiable) ingresar los datos a la base de datos y luego corregirlos que intentar corregirlos durante la carga.¡También obtienes el beneficio de transacciones que te permiten ROLLBACK si no funciona!
Puede importar el archivo CSV a una tabla tal cual, luego escribir una consulta SQL que realice todas las transformaciones necesarias en la tabla importada e inserte el resultado en la tabla de destino.
Entonces algo como:
<(cargar el archivo CSV en temp_table - n, city_name)>
insertar en target_table
seleccione t.n, c.city_id como ciudad
de temp_table t, ciudades c
donde t.nombre_ciudad = c.nombre_ciudad
Un buen consejo sobre el uso de Excel, pero también sugiero que se sienta cómodo con un lenguaje de programación como Python, porque para algunas tareas es más fácil simplemente escribir una secuencia de comandos rápida en Python para hacer el trabajo que tratar de encontrar la función que necesita en Excel o en una versión previa. herramienta hecha que hace el trabajo.
utilice el archivo csv como tabla externa.Luego puede usar SQL para copiar los datos de la tabla externa a su tabla de destino, con todas las posibilidades de SQL.Ver http://www.firebirdsql.org/index.php?op=useful&id=netzka
Yo haría esto con awk.
Por ejemplo, si tuviera esta información en un archivo CSV:
Bob,New York
Jane,San Francisco
Steven,Boston
Marie,Los Angeles
El siguiente comando le dará lo que desea, ejecútelo en el mismo directorio que su archivo CSV (llamado name-city.csv
en este ejemplo).
$ awk -F, '{ print "INSERT INTO PERSON (ID, NAME, CITY_ID) VALUES ((SELECT NEW_GUID FROM CREATE_GUID), '\''"$1"'\'', (SELECT CITY_ID FROM CITY WHERE NAME = '\''"$2"'\''))" }' name-city.csv
Tipo awk --help
para más información.
Acabo de terminar este script VBA que podría resultar útil para este propósito.Todo lo que debería hacer es cambiar la instrucción Insertar para incluir la tabla en cuestión y la lista de columnas (obviamente en la misma secuencia en que aparecen en el archivo de Excel).
Function CreateInsertStatement()
'Output file location and start of the insert statement
SQLScript = "C:\Inserts.sql"
cStart = "Insert Into Holidays (HOLIDAY_ID, NAT_HOLDAY_DESC, NAT_HOLDAY_DTE) Values ("
'Open file for output
Open SQLScript For Output As #1
Dim LoopThruRows As Boolean
Dim LoopThruCols As Boolean
nCommit = 1 'Commit Count
nCommitCount = 100 'The number of rows after which a commit is performed
LoopThruRows = True
nRow = 1 'Current row
While LoopThruRows
nRow = nRow + 1 'Start at second row - presuming there are headers
nCol = 1 'Reset the columns
If Cells(nRow, nCol).Value = Empty Then
Print #1, "Commit;"
LoopThruRows = False
Else
If nCommit = nCommitCount Then
Print #1, "Commit;"
nCommit = 1
Else
nCommit = nCommit + 1
End If
cLine = cStart
LoopThruCols = True
While LoopThruCols
If Cells(nRow, nCol).Value = Empty Then
cLine = cLine & ");" 'Close the SQL statement
Print #1, cLine 'Write the line
LoopThruCols = False 'Exit the cols loop
Else
If nCol > 1 Then 'add a preceeding comma for all bar the first column
cLine = cLine & ", "
End If
If Right(Left(Cells(nRow, nCol).Value, 3), 1) = "/" Then 'Format for dates
cLine = cLine & "TO_DATE('" & Cells(nRow, nCol).Value & "', 'dd/mm/yyyy')"
ElseIf IsNumeric(Left(Cells(nRow, nCol).Value, 1)) Then 'Format for numbers
cLine = cLine & Cells(nRow, nCol).Value
Else 'Format for text, including apostrophes
cLine = cLine & "'" & Replace(Cells(nRow, nCol).Value, "'", "''") & "'"
End If
nCol = nCol + 1
End If
Wend
End If
Wend
Close #1
End Function
Puedes usar el gratis csvsql para hacer esto.
- Instalarlo usando estas instrucciones
Ahora ejecute un comando como este para importar sus datos a su base de datos.Más detalles en los enlaces de arriba, pero sería algo como:
csvsql --db firebase:///d=mydb --insert mydata.csv
Lo siguiente funciona con sqlite y es lo que uso para convertir datos a un formato fácil de consultar.
csvsql --db sqlite:///dump.db --insert mydata.csv
Opción 1:1- ¿Has probado IBExert?IBExpert\Herramientas\Importar datos (versión de prueba o de cliente).
opcion 2:2- sube tu archivo csv a una tabla temporal con F_BLOBLOAD.3- Cree un procedimiento almacenado, que usó 3 funciones (F_StringLength, f_strcopy, f_mid) cruzó toda su cadena, tirando de sus campos para construir su inserto.
Enlaces:2: http://freeadhocudf.org/documentation_english/dok_eng_file.html 3: http://freeadhocudf.org/documentation_english/dok_eng_string.html
Una herramienta que probé recientemente y que funcionó extraordinariamente bien es FSQL.
Escribes un comando IMPORTAR, lo pegas en FSQL
e importa el archivo CSV a la tabla Firebird.