我有一个包含日志数据的数据库文件。数据库包含一个表LOG
,该表包含一个列MSG
。表中有30行,其中该MSG
行的末尾包含字符串“ down”:
$ sqlite3 log.db "select msg from log" | grep down$ | wc -l
30
但是当我尝试通过找到它们时LIKE
,我找不到匹配项:
$ sqlite3 log.db "select msg from log where msg like '%down'" | grep down$ | wc -l
0
这可能是什么原因?
更新:MCVE
CREATE TABLE LOG (MSG VARCHAR(6291456) NOT NULL);
INSERT INTO LOG VALUES (X'666163696c6974793d6461656d6f6e3b636f6d706f6e656e743d6e616d65643b746578743d7368757474696e6720646f776e');
SELECT MSG FROM LOG; -- returns the row
SELECT MSG FROM LOG WHERE MSG LIKE '%down'; -- returns nothing
SELECT MSG FROM LOG WHERE MSG LIKE '%down%'; -- returns nothing
SELECT MSG FROM LOG WHERE CAST(MSG AS VARCHAR) LIKE '%down'; -- returns the row
我不知道为什么从VARCHAR
转换VARCHAR
会有所作为。
更新:另一个MCVE
CREATE TABLE LOG (MSG VARCHAR(6291456) NOT NULL);
INSERT INTO LOG VALUES (X'666163696c6974793d6461656d6f6e3b636f6d706f6e656e743d6e616d65643b746578743d7368757474696e6720646f776e');
INSERT INTO LOG VALUES ('facility=daemon;component=named;text=shutting down');
SELECT ROWID,MSG FROM LOG; -- returns both rows
SELECT ROWID,MSG FROM LOG WHERE MSG LIKE '%down'; -- returns just the second
SELECT ROWID,MSG FROM LOG WHERE MSG LIKE '%down%'; -- returns just the second
SELECT ROWID,MSG FROM LOG WHERE CAST(MSG AS VARCHAR) LIKE '%down'; -- returns both rows
SELECT HEX(MSG) FROM LOG;
鉴于您的示例数据和在不同版本的sqlite上看到的结果,这是肯定的事情。
首先,您要在表中而不是字符串中插入Blob。这些Blob会按原样存储,而不是TEXT
像您正在使用的那样将数字值转换为具有亲和力的列的数值。有关列亲缘关系和隐式数据类型转换的详细信息,请参见文档。
其次,与这些Blob不匹配的sqlite3实例是在SQLITE_LIKE_DOESNT_MATCH_BLOBS
配置选项打开的情况下构建的,而与它们匹配的sqlite3实例是在关闭配置选项的情况下构建的(默认设置)。
如果任一操作数是BLOB,则此编译时选项会使LIKE运算符始终返回False。LIKE的默认行为是在完成比较之前将BLOB操作数强制转换为TEXT。
如果检查PRAGMA compile_options
输出,则应该能够验证它是否正在使用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句