簡體   English   中英

從 CSV 文件生成插入 SQL 語句

[英]Generate insert SQL statements from a CSV file

我需要將一個 csv 文件導入Firebird ,我花了幾個小時嘗試了一些工具,但沒有一個適合我的需要。

主要問題是我一直在嘗試的所有工具(如EMS 數據導入Firebird 數據向導)都希望我的 CSV 文件包含我的表所需的所有信息。

我需要在插入語句中編寫一些自定義 SQL,例如,我有一個帶有城市名稱的 CSV 文件,但是由於我的數據庫已經在另一個表中包含了所有城市(標准化),我需要在插入中編寫一個子選擇語句來查找城市並寫入它的 ID,我還有一個存儲過程來創建 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)

我該如何解決這個問題?

這有點粗糙 - 但對於一次性工作,我有時會使用 Excel。

如果將 CSV 文件導入 Excel,則可以創建一個公式,該公式通過在公式中使用字符串連接來創建 INSERT 語句。 所以 - 如果您的 CSV 文件有 3 列出現在 Excel 的 A、B 和 C 列中,您可以編寫一個公式,例如...

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

然后,您可以將公式復制到所有行,並將答案復制並粘貼到文本文件中,以針對您的數據庫運行。

就像我說的 - 這很粗糙 - 但它可以是完成工作的一種“快速而骯臟”的方式!

好吧,如果它是一個 CSV,並且這是一個一次性過程,請在 Excel 中打開該文件,然后編寫公式以按您希望的任何方式填充數據,然后編寫一個簡單的 Concat 公式來構建您的 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 文件加載到 temp_table - n, city_name)>

插入目標表

選擇 tn, c.city_id 作為城市

來自 temp_table t,城市 c

其中 t.city_name = c.city_name

關於使用 Excel 的好提示,但我也建議熟悉像 Python 這樣的腳本語言,因為對於某些任務,編寫一個快速的 Python 腳本來完成這項工作比嘗試在 Excel 或預做這項工作的工具。

您可以使用免費的csvsql來執行此操作。

  • 使用這些說明安裝它
  • 現在運行類似這樣的命令將您的數據導入到您的數據庫中。 在上面的鏈接中有更多詳細信息,但它會是這樣的:

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

  • 以下適用於 sqlite,是我用來將數據轉換為易於查詢的格式的內容

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

我會用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

使用 csv 文件作為外部表。 然后您可以使用 SQL 將數據從外部表復制到目標表 - 具有 SQL 的所有可能性。 http://www.firebirdsql.org/index.php?op=useful&id=netzka

2020 年幫助我的兩個在線工具:

https://numidian.io/convert/csv/to/sql

https://www.convertcsv.com/csv-to-sql.htm

第二個是基於 JS 的,不上傳你的數據(至少在我寫這篇文章的時候不是)

我最近嘗試過的一個非常有效的工具是FSQL

您編寫了一個 IMPORT 命令,將其粘貼到FSQL然后它將 CSV 文件導入到 Firebird 表中。

選項 1:1- 您是否嘗試過 IBExert? IBExpert \\ Tools \\ 導入數據(試用版或客戶版)。

選項 2:2- 使用 F_BLOBLOAD 將您的 csv 文件上傳到臨時表。 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

你可以使用外殼

sed "s/,/','/g" file.csv > tmp
sed "s/$/'),(/g" tmp > tmp2
sed "s/^./'&/g" tmp2 > insert.sql

然后添加

INSERT INTO PERSON (ID, NAME, CITY_ID) VALUES(
...
);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM