Генерируйте инструкции SQL insert из CSV-файла
Вопрос
Мне нужно импортировать CSV-файл в Жар - птица и я потратил пару часов, пробуя некоторые инструменты, но ни один из них не соответствовал моим потребностям.
Главная проблема заключается в том, что все инструменты, которые я пробовал, такие как Импорт данных EMS и Мастер обработки данных Firebird ожидайте, что мой CSV-файл содержит всю информацию, необходимую для моей Таблицы.
Мне нужно написать некоторый пользовательский SQL в инструкции insert, например, у меня есть CSV-файл с названием города, но поскольку в моей базе данных уже есть все города в другой таблице (нормализованные), мне нужно написать подвыборку в инструкции insert для поиска города и записи его идентификатора, также у меня есть хранимая процедура для создания GUID.
Мой оператор insert был бы примерно таким:
INSERT INTO PERSON (ID, NAME, CITY_ID) VALUES((SELECT NEW_GUID FROM CREATE_GUID), :NAME, (SELECT CITY_ID FROM CITY WHERE NAME = :CITY_NAME)
Как я могу подойти к этому?
Решение
Это немного грубо, но для разовых заданий я иногда использую Excel.
Если вы импортируете CSV-файл в Excel, вы можете создать формулу, которая создает инструкцию INSERT, используя конкатенацию строк в формуле.Итак, если ваш CSV-файл содержит 3 столбца, которые отображаются в столбцах A, B и C в Excel, вы могли бы написать формулу типа...
="INSERT INTO MyTable (Col1, Col2, Col3) VALUES (" & A1 & ", " & B1 & ", " & C1 & ")"
Затем вы можете скопировать формулу по всем вашим строкам, скопировать и вставить ответ в текстовый файл для запуска в вашей базе данных.
Как я уже сказал, это грубо, но это может быть довольно "быстрый и грязный" способ выполнить работу!
Другие советы
Что ж, если это CSV, и это одноразовый процесс, откройте файл в Excel, а затем напишите формулы для заполнения ваших данных любым удобным для вас способом, а затем напишите простую формулу объединения для построения вашего SQL, а затем скопируйте эту формулу для каждой строки.Вы получите большое количество инструкций SQL, которые вы можете выполнить в любом месте, где захотите.
Фабио,
Я делал то, что Vaibhav делал много раз, и это хороший "быстрый и грязный" способ получения данных в базу данных.
Если вам нужно сделать это несколько раз или по какому-то расписанию, то более надежным способом является загрузка CSV-данных "как есть" в рабочую таблицу (т.Е. customer_dataload), а затем использование стандартных инструкций SQL для заполнения недостающих полей.
(Я не знаю синтаксиса Firebird, но что-то вроде ...)
UPDATE person
SET id = (SELECT newguid() FROM createguid)
UPDATE person
SET cityid = (SELECT cityid FROM cities WHERE person.cityname = cities.cityname)
и т.д.
Обычно гораздо быстрее (и надежнее) получить данные В базу данных, а затем исправить их, чем пытаться исправить данные во время загрузки.Вы также получаете преимущество от транзакций, позволяющее вам выполнить ОТКАТ, если это не сработает!!
Вы могли бы импортировать CSV-файл в таблицу как есть, затем написать SQL-запрос, который выполняет все необходимые преобразования в импортированной таблице и вставляет результат в целевую таблицу.
Так что что-то вроде:
<(загрузите CSV-файл во временную таблицу - n, city_name)>
вставить в target_table
выберите t.n, c.city_id в качестве города
из temp_table t, города c
где t.city_name = c.city_name
Хороший совет по использованию Excel, но я также предлагаю освоиться с таким скриптовым языком, как Python, потому что для решения некоторых задач проще просто написать быстрый скрипт на python для выполнения задания, чем пытаться найти нужную функцию в Excel или готовый инструмент, который выполняет эту работу.
используйте csv-файл в качестве внешней таблицы.Затем вы можете использовать SQL для копирования данных из внешней таблицы в вашу целевую таблицу - со всеми возможностями SQL.Видишь http://www.firebirdsql.org/index.php?op=useful&id=netzka
Я бы сделал это с awk ( авк ).
Например, если у вас была эта информация в CSV-файле:
Bob,New York
Jane,San Francisco
Steven,Boston
Marie,Los Angeles
Следующая команда даст вам то, что вы хотите, запустите в том же каталоге, что и ваш CSV-файл (с именем name-city.csv
в этом примере).
$ 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
Тип awk --help
для получения дополнительной информации.
Только что закончил этот VBA-скрипт, который может быть полезен для этой цели.Все, что нужно сделать, это изменить инструкцию Insert, чтобы включить соответствующую таблицу и список столбцов (очевидно, в той же последовательности, в какой они отображаются в файле 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
Вы можете воспользоваться бесплатным csvsql чтобы сделать это.
- Установите его используя эти инструкции
Теперь выполните команду, подобную so, чтобы импортировать ваши данные в вашу базу данных.Более подробная информация по ссылкам выше, но это было бы что-то вроде:
csvsql --db firebase:///d=mydb --insert mydata.csv
Следующее работает с sqlite, и это то, что я использую для преобразования данных в удобный формат запроса
csvsql --db sqlite:///dump.db --insert mydata.csv
вариант 1:1- вы пробовали IBExert?IBExpert \ Инструменты \ Импорт данных (пробная или клиентская версия).
вариант 2:2- загрузите ваш CSV-файл во временную таблицу с помощью F_BLOBLOAD.3. создайте хранимую процедуру, которая использовала бы 3 функции (f_stringlength, f_strcopy, f_MID) вы перечеркиваете всю свою строку, извлекая свои поля для создания ВСТАВКИ.
Ссылки:2: http://freeadhocudf.org/documentation_english/dok_eng_file.html 3: http://freeadhocudf.org/documentation_english/dok_eng_string.html
Инструмент, который я недавно попробовал и который сработал на удивление хорошо, - это FSQL.
Вы пишете команду ИМПОРТА, вставляете ее в FSQL
и он импортирует CSV-файл в таблицу Firebird.