将 csv 导入 sqlite3 时将十六进制解释为数字

问题描述 投票:0回答:1

我在 sqlite 中处理十六进制数字时遇到问题。

给定一个包含数字的 CSV 文件,其中一个写为十六进制 (0x1)

❯ cat my.csv
A,B
1,0x1

导入并检查架构

❯ sqlite3 my.db ".import --csv my.csv somet"
❯ sqlite3 my.db ".schema somet"
CREATE TABLE IF NOT EXISTS "somet"(
"A" TEXT, "B" TEXT);

现在我们可以选择 A 作为实数(没有单引号),但 B 不能。

❯ sqlite3 my.db "select * from somet where a = 0x1;"
1|0x1

❯ sqlite3 my.db "select * from somet where b = 0x1;"

这出乎我的意料。我们可以看到,在对 A 列进行过滤时,SQLite 可以理解数字的十六进制表示形式,但不能对 B 列进行过滤。

在查看 A 的输出时,我们还看到 b 并未存储为数字,而是似乎存储为二进制十六进制字符串。

那么,鉴于sqlite3理解十六进制表示,并且它将使用数字作为“数字”,当导入csv时,为什么B不作为数字导入?

sqlite csv
1个回答
0
投票
通过

sqlite3

 shell 进行 
CSV 导入会将值作为字符串插入。任何到其他存储类型的转换都是由底层
INSERT
基于列类型及其亲和性完成的。

表格的

B
列具有
TEXT
类型,这意味着它具有文本亲和力;所有内容都存储为字符串(空值和 blob 除外)。如果您为列提供具有数字亲和力的类型,例如
INTEGER
,则包含整数文字的字符串将转换为整数,除了

...十六进制整数文字不被认为是格式正确的,并且存储为 TEXT。 (这样做是为了与 3.8.6 2014-08-15 版本之前的 SQLite 版本保持历史兼容性,其中十六进制整数文字首次引入 SQLite。)

在导入之前,您必须更改 ETL 流程,将这些十六进制值替换为以 10 为基数的整数(并提前创建具有正确列类型的表),或者编写更智能的导入脚本。

© www.soinside.com 2019 - 2024. All rights reserved.