Генерировать операторы вставки SQL из файла CSV - PullRequest
51 голосов
/ 12 августа 2008

Мне нужно импортировать CSV-файл в Firebird , и я потратил пару часов, пробуя некоторые инструменты, и ни один из них не соответствовал моим потребностям.

Основная проблема заключается в том, что все инструменты, которые я пробовал, например Импорт данных EMS и Мастер данных Firebird , ожидают, что мой CSV-файл содержит всю информацию, необходимую для моей таблицы.

Мне нужно написать некоторый пользовательский SQL в операторе вставки, например, у меня есть файл CSV с названием города, но, поскольку в моей базе данных уже есть все города в другой таблице (нормализовано), мне нужно написать подвыбор в операторе вставки для поиска города и записи его идентификатора у меня также есть хранимая процедура для создания GUIDS.

Мой оператор вставки будет выглядеть примерно так:

INSERT INTO PERSON (ID, NAME, CITY_ID) VALUES((SELECT NEW_GUID FROM CREATE_GUID), :NAME, (SELECT CITY_ID FROM CITY WHERE NAME = :CITY_NAME)

Как я могу подойти к этому?

Ответы [ 10 ]

106 голосов
/ 12 августа 2008

Это немного грубо - но для разовых работ я иногда использую Excel.

Если вы импортируете файл CSV в Excel, вы можете создать формулу, которая создает оператор INSERT, используя конкатенацию строк в формуле. Итак, если ваш CSV-файл содержит 3 столбца, которые отображаются в столбцах A, B и C в Excel, вы можете написать формулу, например ...

="INSERT INTO MyTable (Col1, Col2, Col3) VALUES (" & A1 & ", " & B1 & ", " & C1 & ")"

Затем вы можете повторить формулу по всем строкам, скопировать и вставить ответ в текстовый файл для запуска в вашей базе данных.

Как я уже сказал - это грубо - но это может быть довольно «быстрый и грязный» способ выполнить работу!

8 голосов
/ 12 августа 2008

Что ж, если это CSV, и это однократный процесс, откройте файл в Excel, а затем напишите формулы для заполнения ваших данных любым желаемым образом, а затем напишите простую формулу Concat для построения SQL, а затем скопируйте эту формулу для каждой строки. Вы получите большое количество операторов SQL, которые вы можете выполнять где угодно.

5 голосов
/ 12 августа 2008

Fabio

Я делал то, что делал Вайбхав много раз, и это хороший «быстрый и грязный» способ получить данные в базу данных.

Если вам нужно сделать это несколько раз или по расписанию какого-либо типа, то более надежным способом является загрузка данных 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)

и т.д.

Обычно гораздо быстрее (и надежнее) получить данные в базу данных и затем исправить данные, чем пытаться исправить данные во время загрузки. Вы также получаете выгоду от транзакций, позволяющих выполнять откат, если он не работает !!

3 голосов
/ 12 августа 2008

Вы можете импортировать файл CSV в таблицу как есть, а затем написать запрос SQL, который выполняет все необходимые преобразования для импортированной таблицы и вставляет результат в целевую таблицу.

Так что-то вроде:

<(загрузить CSV-файл в temp_table - n, название города)>

вставить в target_table

выберите t.n, c.city_id в качестве города

из temp_table t, города c

где t.city_name = c.city_name

Хороший совет по использованию Excel, но я также предлагаю освоиться с языком сценариев, таким как Python, потому что для какой-то задачи проще просто написать быстрый скрипт Python, чтобы выполнить работу, чем пытаться найти нужную вам функцию в Excel или готовый инструмент, который делает эту работу.

1 голос
/ 06 марта 2017

Вы можете использовать бесплатный csvsql , чтобы сделать это.

  • Установите его , следуя этим инструкциям
  • Теперь запустите такую ​​команду, чтобы импортировать ваши данные в вашу базу данных. Подробности по ссылкам выше, но это будет что-то вроде:

    csvsql --db firebase:///d=mydb --insert mydata.csv

  • Следующее работает с sqlite и используется для преобразования данных в простой для запроса формат

    csvsql --db sqlite:///dump.db --insert mydata.csv

1 голос
/ 09 марта 2011

использовать csv-файл в качестве внешней таблицы. Затем вы можете использовать SQL для копирования данных из внешней таблицы в таблицу назначения - со всеми возможностями SQL. Смотри http://www.firebirdsql.org/index.php?op=useful&id=netzka

1 голос
/ 05 февраля 2010

Только что закончил этот VBA-скрипт, который может пригодиться для этой цели. Все, что нужно сделать, это изменить оператор вставки, включив в него соответствующую таблицу и список столбцов (очевидно, в той же последовательности, в которой они отображаются в файле 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
1 голос
/ 12 августа 2008

Я бы сделал это с 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 для получения дополнительной информации.

0 голосов
/ 09 марта 2011

вариант 1: 1 - вы пробовали IBExert? IBExpert \ Инструменты \ Импорт данных (пробная или пользовательская версия).

вариант 2: 2 - загрузить CSV-файл во временную таблицу с помощью F_BLOBLOAD. 3 - создать хранимую процедуру, в которой используются 3 функции (f_stringlength, f_strcopy, f_MID) Вы пересекаете всю свою строку, натягивая поля, чтобы создать свой INSERT INTO.

ссылки: 2: http://freeadhocudf.org/documentation_english/dok_eng_file.html 3: http://freeadhocudf.org/documentation_english/dok_eng_string.html

0 голосов
/ 21 января 2010

Инструмент, который я недавно попробовал и который отлично работал, это FSQL .

Вы пишете команду IMPORT, вставляете ее в FSQL и она импортирует файл CSV в таблицу Firebird.

...