题
我需要将 csv 文件导入 火鸟 我花了几个小时尝试一些工具,但没有一个适合我的需求。
主要问题是我尝试过的所有工具都像 EMS数据导入 和 火鸟数据向导 期望我的 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)
ETC。
通常,将数据放入数据库然后修复数据比在上传期间尝试修复数据要快得多(也更可靠)。您还可以获得事务的好处,如果它不起作用,您可以回滚!
您可以将 CSV 文件按原样导入到表中,然后编写一个 SQL 查询,对导入的表执行所有必需的转换,并将结果插入到目标表中。
所以像这样:
<(将 CSV 文件加载到 temp_table - n, city_name)>
插入目标表
选择 t.n, c.city_id 作为城市
来自临时表 t,城市 c
其中 t.city_name = c.city_name
关于使用 Excel 的好提示,但我也建议熟悉 Python 等脚本语言,因为对于某些任务,编写一个快速的 Python 脚本来完成工作比尝试在 Excel 或预编译器中查找所需的函数更容易。制作了完成这项工作的工具。
使用 csv 文件作为外部表。然后,您可以使用 SQL 将数据从外部表复制到目标表 - 具有 SQL 的所有可能性。看 http://www.firebirdsql.org/index.php?op=useful&id=netzka
我会这样做 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
选项1:1-您尝试过 IBExert 吗?IBExpert \ 工具 \ 导入数据(试用版或客户版)。
选项2:2- 使用 F_BLOBLOAD 将 csv 文件上传到临时表。3-创建一个存储过程,该过程使用了3个功能(f_stringlength,f_strcopy,f_mid),您可以穿过所有字符串,从而拉动字段以构建插入。
链接: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 表中。