60

我需要将一个 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)

我该如何处理?

4

12 回答 12

124

这有点粗糙 - 但对于临时工作,我有时会使用 Excel。

如果将 CSV 文件导入 Excel,则可以创建一个公式,该公式通过在公式中使用字符串连接来创建 INSERT 语句。所以 - 如果您的 CSV 文件有 3 列出现在 Excel 的 A、B 和 C 列中,您可以编写如下公式...

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

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

就像我说的那样——它很粗糙——但它可能是一种“快速而肮脏”的完成工作的方式!

于 2008-08-11T21:07:51.287 回答
8

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

于 2008-08-11T21:02:14.620 回答
5

法比奥,

我已经做过 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)

等等

通常,将数据导入数据库然后修复数据比在上传期间尝试修复数据要快得多(也更可靠)。您还可以获得交易的好处,如果它不起作用,您可以回滚!

于 2008-08-11T21:14:21.897 回答
3

您可以将 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 或预制造完成这项工作的工具。

于 2008-08-11T21:13:51.290 回答
3

我会用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以获取更多信息。

于 2008-08-12T02:25:36.200 回答
3

2020 年帮助我的两个在线工具:

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

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

第二个是基于 JS 的,不会上传你的数据(至少在我写这篇文章的时候没有)

于 2020-08-20T00:33:34.847 回答
2

您可以使用免费的csvsql来执行此操作。

  • 使用这些说明安装它
  • 现在运行这样的命令将数据导入数据库。上面链接中的更多详细信息,但它会是这样的:

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

  • 以下适用于 sqlite,并且是我用来将数据转换为易于查询的格式

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

于 2017-03-06T14:27:13.833 回答
1

刚刚完成了这个 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
于 2010-02-05T16:18:41.140 回答
1

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

于 2011-03-09T16:48:57.303 回答
0

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

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

于 2010-01-21T16:59:25.647 回答
0

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

于 2011-03-09T15:47:20.020 回答
0

你可以使用外壳

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(
...
);
于 2020-04-17T14:56:04.727 回答