Generate Insert SQL statements from a csv file

2019-01-13 09:32发布

I need to import a csv file into Firebird and I've spent a couple of hours trying out some tools and none fit my needs.

The main problem is that all the tools I've been trying like EMS Data Import and Firebird Data Wizard expect that my csv file contains all the information needed by my Table.

I need to write some custom SQL in the insert statement, for example, I have a cvs file with the city name, but as my database already has all the cities in another table (normalized), I need to write a subselect in the insert statement to lookup for the city and write its ID, also I have a stored procedure to cread GUIDS.

My Insert statement would be something like this:

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

I know that it is very easy to write an application to do this, but I don't like to reinvent the wheel, and I'm sure that there are some tools out there to do it.

Can you guys give me some advice?

14条回答
小情绪 Triste *
2楼-- · 2019-01-13 10:04

It's a bit crude - but for one off jobs, I sometimes use Excel.

If you import the CSV file into Excel, you can create a formula which creates an INSERT statement by using string concatenation in the formula. So - if your CSV file has 3 columns that appear in columns A, B and C in Excel, you could write a formula like...

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

Then you can replicate the formula down all of your rows, and copy and paste the answer into a text file to run against your database.

Like I say - it's crude - but it can be quite a 'quick and dirty' way of getting a job done!

查看更多
闹够了就滚
3楼-- · 2019-01-13 10:05

You could try fbcopy and fbexport tools.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-13 10:06

I use a slight variation on Balloon's Excel technique.

I highly recommend downloading the free ASAP Utilities plug-in for Excel. One of the many time saving tools they include are insert before current value and insert after current value options.

Those should let you reach a solution quicker by helping you build your insert statements.

查看更多
一纸荒年 Trace。
5楼-- · 2019-01-13 10:07

I'd do this with awk.

For example, if you had this information in a CSV file:

Bob,New York
Jane,San Francisco
Steven,Boston
Marie,Los Angeles

The following command will give you what you want, run in the same directory as your CSV file (named name-city.csv in this example).

$ 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

Type awk --help for more information.

查看更多
干净又极端
6楼-- · 2019-01-13 10:17

Well, if it's a CSV, and it this is a one time process, open up the file in Excel, and then write formulas to populate your data in any way you desire, and then write a simple Concat formula to construct your SQL, and then copy that formula for every row. You will get a large number of SQL statements which you can execute anywhere you want.

查看更多
▲ chillily
7楼-- · 2019-01-13 10:22

Just finished this VBA script which might be handy for this purpose. All should need to do is change the Insert statement to include the table in question and the list of columns (obviously in the same sequence they appear on the Excel file).

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
查看更多
登录 后发表回答