在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"]]
答案 0 :(得分:0)
X前缀将HEX值转换为字符串。
sqlite> SELECT X'41';
A
sqlite> SELECT X'42';
B
sqlite> SELECT X'4242';
BB
sqlite> SELECT X'54545831';
TTX1 # Do not forget this one
sqlite> SELECT X'54';
T
sqlite> SELECT X'58';
X
不要让我们看到你的代码,
sqlite> select * from batches;
TTX1|0|2018-02-20 11:40:46 +0100|2018-02-20 11:40:46 +0100
TTX2|0|2018-02-20 11:40:54 +0100|2018-02-20 11:40:54 +0100
TTX3|0|2018-02-20 11:41:02 +0100|2018-02-20 11:41:02 +0100
以下查询返回空集。
sqlite> SELECT * FROM batches WHERE batch = 'TTX1';
sqlite> SELECT * FROM batches WHERE batch = 'TTX2';
sqlite> SELECT * FROM batches WHERE batch = 'TTX3';
不插入普通的字符串数据。
sqlite> INSERT INTO batches VALUES('TTX2',0,'2018-02-20 11:40:46 +0100','2018-02-20 11:40:46 +0100');
sqlite> select * from batches;
TTX1|0|2018-02-20 11:40:46 +0100|2018-02-20 11:40:46 +0100
TTX2|0|2018-02-20 11:40:54 +0100|2018-02-20 11:40:54 +0100
TTX3|0|2018-02-20 11:41:02 +0100|2018-02-20 11:41:02 +0100
TTX2|0|2018-02-20 11:40:46 +0100|2018-02-20 11:40:46 +0100
sqlite> select * from batches where batch = 'TTX2';
TTX2|0|2018-02-20 11:40:46 +0100|2018-02-20 11:40:46 +0100
让我们检查一些平等。
sqlite> Select 123 = 123;
1
sqlite> Select X'54545831' = 'TTX1';
0
响应batch = TTX{number}
的数据是您作为字符串插入的数据。但其他人没有遇到这种情况。
答案 1 :(得分:0)
这些值不存储为十六进制,它们存储为blob。在SQL语句中,编写blob的唯一方法是使用blob literal,其中blob的字节用十六进制数字表示。
无论编写什么程序,数据库都将这些值写为blob。
要搜索blob,请将搜索值转换为blob:
SELECT * FROM batches WHERE batch = CAST('TTX3' AS BLOB);
或者,修改数据库以使其包含文本值(可能会破坏其他程序):
UPDATE batches SET batch = CAST(batch AS TEXT);