从 CSV 文件生成插入 SQL 语句

从 CSV 文件生成插入 SQL 语句

Generate insert SQL statements from a CSV file

我需要将 csv 文件导入 Firebird,我花了几个小时尝试了一些工具,但没有一个适合我的需要。

主要问题是我一直在尝试的所有工具(例如 EMS 数据导入和 Firebird 数据向导)都希望我的 CSV 文件包含我的表所需的所有信息。

我需要在插入语句中编写一些自定义 SQL,例如,我有一个带有城市名称的 CSV 文件,但是由于我的数据库已经在另一个表中包含了所有城市(规范化),我需要编写一个子选择在查找城市并写入其 ID 的插入语句中,我还有一个存储过程来读取 GUIDS。

我的插入语句是这样的:

1
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 列中,您可以编写如下公式...

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

然后您可以将公式复制到所有行中,然后将答案复制并粘贴到文本文件中以针对您的数据库运行。

就像我说的 - 它很粗糙 - 但它可能是完成工作的一种"快速而肮脏"的方式!


好吧,如果它是一个 CSV,而且这是一个一次性的过程,请在 Excel 中打开文件,然后编写公式以您希望的任何方式填充您的数据,然后编写一个简单的 Concat 公式来构建您的SQL,然后为每一行复制该公式。您将获得大量的 SQL 语句,您可以在任何地方执行这些语句。


我会用 awk 来做这个。

例如,如果您在 CSV 文件中有此信息:

1
2
3
4
Bob,NEW York
Jane,San Francisco
Steven,Boston
Marie,Los Angeles

以下命令将为您提供所需的内容,在与您的 CSV 文件相同的目录中运行(在此示例中名为 name-city.csv)。

1
$ 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 以获取更多信息。


法比奥,

我已经多次完成 Vaibhav 所做的事情,这是一种将数据导入数据库的"快速而肮脏"的好方法。

如果您需要执行此操作几次,或按某种类型的计划执行此操作,那么更可靠的方法是将 CSV 数据"按原样"加载到工作表中(即 customer_dataload),然后使用标准 SQL 语句填充缺失的字段。

(我不知道 Firebird 的语法 - 但类似...)

1
2
3
4
5
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:

1
2
3
4
 INSERT INTO target_table
 SELECT t.n, c.city_id AS city
 FROM temp_table t, cities c
 WHERE t.city_name = c.city_name

关于使用 Excel 的好建议,但我也建议熟悉 Python 之类的脚本语言,因为对于某些任务来说,编写一个快速的 Python 脚本来完成这项工作比尝试在 Excel 中找到所需的函数或完成这项工作的预制工具。


n


n


使用 csv 文件作为外部表。然后,您可以使用 SQL 将数据从外部表复制到目标表 - 使用 SQL 的所有可能性。
见 http://www.firebirdsql.org/index.php?op=useful


刚刚完成了这个 VBA 脚本,它可能对这个目的很方便。只需更改 Insert 语句以包含相关表和列列表(显然与它们在 Excel 文件中出现的顺序相同)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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

n


选项 1:
1-您尝试过 IBExert 吗? IBExpert \\\\ 工具 \\\\ 导入数据(试用版或客户版)。

选项 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


我最近尝试过的一个非常好用的工具是 FSQL。

您编写一个 IMPORT 命令,将其粘贴到 FSQL 中,然后它将 CSV 文件导入到 Firebird 表中。


推荐阅读