如何在 Firebird 中创建外部表并将其与 CSV 文件相关联?

How do I create an external table in Firebird and relate it to a CSV file?

提问人:C Matt 提问时间:8/26/2023 最后编辑:Mustafa ÖzçetinC Matt 更新时间:8/27/2023 访问量:95

问:

我使用逗号创建了一个 CSV 文件来分隔字段。每行有两个字段值,用逗号分隔。我使用两个字段创建了一个外部表,并引用了 CSV 文件的 filespec。当我使用以下命令时:

insert into realtable (field1, field2) select from externaltable (field1, field2);

CSV 文件中的所有数据都插入到 Field1 中。使用 create table 命令时,似乎无法识别逗号。创建外部表时如何指示分隔符值?

Firebird 外部表

评论

0赞 user13964273 8/26/2023
如果外部表本身不是你的目标,你可以看看 stackoverflow.com/questions/2114090/...

答:

1赞 Mark Rotteveel 8/26/2023 #1

Firebird 外部表使用二进制格式。它与 Firebird 在内存中保存一行时使用的格式基本相同(当一行写入普通表中的磁盘时,它会对该行应用 RLE 压缩,但不适用于外部表)。

换句话说,您不能使用外部表直接读取 CSV 文件。

您可以使用一个技巧来使 Firebird 外部表作为固定宽度的文本格式工作(也就是说,一列在每行中具有相同的宽度,并且您需要使用空格将值填充到列的声明长度)。为此,您只需要使用列,并为换行符添加一个额外的列(如果仅使用 LF,则为 a,如果使用 CR/LF,则为 a)。建议显式指定列的字符集。请注意,不建议使用像 UTF-8 这样的多字节字符集来执行此技巧(与 UTF-8 一样,它将不再是固定宽度的文本(仅以字节为单位的固定宽度),以字节为单位的长度将是字符长度的 4 倍)。CHARCHAR(1)CHAR(2)

或者,您可以使用工具将 CSV 文件转换为 Firebird 外部表。我写了这样一个工具,Firebird External Table Generator,或ext-table-gen(它是免费和开源的)。当前版本仅支持如上所述的列,下一版本还将支持数据类型 、 、 、 、 、 和 。CHARSMALLINTINTEGERBIGINTINT128DATETIMETIMESTAMPNUMERICDECIMAL

它附带了一本手册,更详细地描述了它的用法,但转述手册中的示例,您可以从 CSV 文件派生外部表的定义:

CSV 文件:

ID,Lastname,Firstname,Email
1,Doe,John,[email protected]
2,Doe,Jane,[email protected]
3,Deer,Jason,[email protected]
4,Deer,Jillian,[email protected]

生成外部表文件的命令:

ext-table-gen --csv-file=C:\path\to\persons.csv --table-file=C:\path\to\persons.dat --config-out=C:\path\to\persons.xml

这将生成一个外部表文件 ,并生成一个 XML 配置文件 。您可以进一步修改此文件。例如,如果要重复使用配置来重复导入 CSV 的新版本,则定义比从初始文件派生的列更宽的列可能是有意义的。persons.datpersons.xml

配置文件还显示了定义外部表所需的 DDL。注意:如果更改列定义,则还要确保修改 DDL,或重新生成配置文件,当然还要重新生成 persons.dat,使其符合更广泛的格式。

例如,它为外部表生成以下 DDL:

create table "DEFAULT_EXTERNAL_TABLE_NAME" external file 'C:\path\to\persons.dat' (
  "ID" char(1) character set ISO8859_1,
  "Lastname" char(4) character set ISO8859_1,
  "Firstname" char(7) character set ISO8859_1,
  "Email" char(19) character set ISO8859_1,
  "LF" char(1) character set ASCII default _ASCII x'0a'
);

执行 DDL,然后您可以从 ext-table-gen 创建的文件中进行选择。persons.dat

select * from DEFAULT_EXTERNAL_TABLE_NAME

评论

0赞 C Matt 8/27/2023
我会试试你的工具。非常感谢您,因为我还有另一个项目需要导入 400 万条记录。
0赞 Mark Rotteveel 8/27/2023
@CMatt 根据您的需求,等待 2.0 版可能是值得的,我希望在下周(或后一周)发布,因为它将引入对更广泛的数据类型的支持,而不仅仅是 .CHAR
0赞 C Matt 8/28/2023
Mark,我还需要支持其他分隔符,例如空制表符和竖线。
0赞 Mark Rotteveel 8/28/2023
@CMatt 2.0 版中也即将推出(事实上,这是我在发布它之前添加的最后一件事),github.com/mrotteveel/ext-table-gen/issues/18
0赞 Mark Rotteveel 9/1/2023
@CMatt我刚刚发布了 2.0 版,您可以在 github.com/mrotteveel/ext-table-gen/releases/latest