在Ruby脚本中,我需要从现有的g SQLite3数据库中读取一些值。

DB = SQLite3::Database.open "#{App.root}/db/dm4sea_#{App.env}.db"


该数据库有1个表(批次),其结构如下

DB.execute "PRAGMA table_info(batches);"
=> [[0, "batch", "VARCHAR(30)", 0, nil, 1],
   [1, "fdl", "INT", 0, nil, 0],
   [2, "created_at", "DATETIME", 0, nil, 0],
   [3, "updated_at", "DATETIME", 0, nil, 0]]


当前内容是

DB.execute "SELECT * FROM batches"
=> [["TTX1", 0, "2018-02-20 10:26:17 +0100", "2018-02-20 10:26:17 +0100"],
    ["TTX2", 0, "2018-02-20 10:36:33 +0100", "2018-02-20 10:36:33 +0100"],
    ["TTX3", 0, "2018-02-20 10:39:52 +0100", "2018-02-20 10:39:52 +0100"]]


但是,令我惊讶的是,发生了以下情况

DB.execute "SELECT * FROM batches WHERE batch = 'TTX3'"
=> []


这里是数据库转储

sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE batches (
          batch VARCHAR(30) PRIMARY KEY,
          fdl INT,
          created_at DATETIME,
          updated_at DATETIME
        );
INSERT INTO batches VALUES(X'54545831',0,'2018-02-20 11:40:46 +0100','2018-02-20 11:40:46 +0100');
INSERT INTO batches VALUES(X'54545832',0,'2018-02-20 11:40:54 +0100','2018-02-20 11:40:54 +0100');
INSERT INTO batches VALUES(X'54545833',0,'2018-02-20 11:41:02 +0100','2018-02-20 11:41:02 +0100');
CREATE INDEX batches_batch
        ON batches (batch);
CREATE INDEX batches_fdl
        ON batches (fdl);
COMMIT;


为什么将批次存储为十六进制值?

DB.execute "SELECT * FROM batches WHERE batch = X'54545833'"
=> [["TTX3", 0, "2018-02-20 11:41:02 +0100", "2018-02-20 11:41:02 +0100"]]

最佳答案

这些值不存储为十六进制,而是存储为Blob。在SQL语句中,写入blob的唯一方法是使用blob literal,其中blob的字节用十六进制数字表示。

不论哪个程序写数据库,都将这些值写为blob。

要搜索斑点,请将搜索值转换为斑点:



SELECT * FROM batches WHERE batch = CAST('TTX3' AS BLOB);


或者,修改数据库,使其包含文本值(这可能会破坏其他程序):

UPDATE batches SET batch = CAST(batch AS TEXT);

09-11 11:01