从csv文件生成插入SQL语句

时间:2020-03-05 18:39:02  来源:igfitidea点击:

我需要将一个csv文件导入Firebird,并且花了几个小时尝试了一些工具,但这些工具都不符合我的需求。

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

我需要在insert语句中编写一些自定义SQL,例如,我有一个带有城市名称的cvs文件,但是由于我的数据库已经在另一个表中(标准化的)所有城市,因此我需要在insert中编写一个subselect语句以查找城市并写入其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)

我知道编写一个应用程序来做到这一点非常容易,但是我不喜欢重新发明轮子,而且我敢肯定有一些工具可以做到这一点。

你们能给我一些建议吗?

解决方案

回答

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

回答

这有点粗糙,但要完成一份工作,我有时会使用Excel。

如果将CSV文件导入Excel,则可以创建一个公式,该公式通过在公式中使用字符串串联来创建INSERT语句。因此,如果CSV文件有3列显示在Excel中的A,B和C列中,则可以编写如下公式:

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

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

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

回答

我们可以按原样将CSV文件导入到表中,然后编写一个SQL查询,对导入的表进行所有必需的转换并将结果插入目标表中。

所以像这样:

<(load the CSV file into temp_table - n, city_name)>
  
  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或者pre-pres中找到所需的功能要容易得多。做这个工作的工具。

回答

法比奥

我已经完成了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)

等等。

通常,将数据获取到数据库中然后修复数据比在上载期间尝试修复数据要快得多(并且更可靠)。我们还可以获得交易的好处,如果不起作用,可以回滚!!

回答

有时,我使用世界上最简单的代码生成器(Javascript版)。它在线,但是只是javascript,数据不会随处可见。还有一个asp版本,具有更多功能。

回答

我会用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), '\''""'\'', (SELECT CITY_ID FROM CITY WHERE NAME = '\''""'\''))" }' name-city.csv

输入awk --help了解更多信息。

回答

我对Balloon的Excel技术使用了一些细微的变化。

我强烈建议下载免费的Excel ASAP Utilities插件。它们包括的许多省时工具之一是在当前值之前插入和在当前值之后插入选项。

这些应该可以构建插入语句,从而使我们更快地找到解决方案。

回答

我们可以尝试使用fbcopy和fbexport工具。

回答

我最近尝试的一种非常出色的工具是FSQL。

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

回答

刚刚完成了此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