【问题标题】:How to insert binary data into sqlite3 database in bash?如何在bash中将二进制数据插入sqlite3数据库?
【发布时间】:2012-04-28 23:15:49
【问题描述】:

我想在 bash 脚本中将二进制数据(png、jpg、gif 等)插入到 sqlite3 数据库中。
我使用独立的二进制文件sqlite3。如何编写 SQL 语句?
感谢您的帮助。

【问题讨论】:

  • 我不确定命令行工具是否会让您插入这样的任意数据。我猜你可以先对数据进行base64编码。

标签: sql bash sqlite binary


【解决方案1】:

正如我在@sixfeetsix 答案的评论中提到的,插入数据只是问题的一半。一旦它进入,您需要将其取出。我们可以为此使用 xxd。

#A nice hubble image to work with.
echo 'http://asd.gsfc.nasa.gov/archive/hubble/Hubble_20th.jpg' > imageurl.txt
image=imageurl.txt
curl $image > image.jpg

#Insert the image, using hexdump to read the data into SQLite's BLOB literal syntax.
echo "create table images (image blob);" | sqlite3 images.db
echo "insert into images (image) values(x'$(hexdump -ve '1/1 "%0.2X"' image.jpg)');" | sqlite3 images.db 2>&1

#Select just the one image, then use xxd to convert from hex back to binary.
echo "select quote(image) from images limit 1 offset 0;" | sqlite3 images.db  | tr -d "X'" | xxd -r -p > newimage.jpg
eog newimage.jpg 

【讨论】:

    【解决方案2】:

    这是一种方法。文件test.jpghexdump编辑成sqlite的二进制文字格式后,插入到数据库foodb的表foo中:

    [someone@somewhere tmp]$ sqlite3 foodb "create table foo (bar blob);"
    [someone@somewhere tmp]$ echo "insert into foo values (X'`hexdump -ve '1/1 "%.2x"' test.jpg`');" | sqlite3 foodb
    

    编辑

    在这里我们看到数据以“全保真”方式存储,因为 .jpg 文件可以恢复:

    [somneone@somewhere tmp]$ sqlite3 foodb "select quote(bar) from foo;" | perl -ne 's/([0-9a-f]{2})/print chr hex $1/gie' > bla.jpg 
    [somneone@somewhere tmp]$ ll *.jpg
    -rw-rw-r-- 1 someone someone 618441 Apr 28 16:59 bla.jpg
    -rw-rw-r-- 1 someone someone 618441 Apr 28 16:37 test.jpg
    [someone@somewhere tmp]$ md5sum *.jpg 
    3237a2b76050f2780c592455b3414813  bla.jpg
    3237a2b76050f2780c592455b3414813  test.jpg
    

    此外,这种方法节省空间,因为它使用 sqlite 的 BLOB 类型存储 .jpg。它不会使用例如 base64 编码对图像进行字符串化。

    [someone@somewhere tmp]$ ll foodb 
    -rw-r--r-- 1 someone someone 622592 Apr 28 16:37 foodb
    

    【讨论】:

    • 这行不通:(我知道它行不通,因为我要在 20 分钟前发布它,但无法让一些测试用例工作。具体来说,如果您查询该列,结果将在第一个 0x00 处被截断(在 jpeg 中,您几乎可以保证在某处有一个 NULL 字节)。如果您选择 quote(bar) 它会给您原始的 x'...'
    • @DavidSouther:二进制数据中有 0x00 不是很正常吗?请阅读有关 BLOB 类型的 sqlite 的信息。您所期望的是以某种人类可读格式存储的数据,这种格式的空间效率较低; OP 没有这样的要求。
    • 这是很正常的事情。我期待,并且确实是正确的,因为该 sqlite 正确地将 0x00 存储在 blob 列中。问题是当您在该列上运行select 时,select 只会返回到第一个 0x00。这就是我要指出的问题,修复是我们通过使用select quote() 并将该十六进制转换回二进制输出来包含在我们的编辑中。
    • 我喜欢你的编辑 :) 现在我唯一可以声称的是 xxd 比你的 perl 命令短!我们再次看到了 Unix 方式的力量。
    • @DavidSouther:我只想指出,OP 询问插入。
    猜你喜欢
    • 2014-04-11
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2018-12-21
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多