C ++,sqlite3。将BLOB字段用作查询条件时如何处理?

时间:2019-02-21 11:22:18

标签: c++ sqlite

我有一个sqlit3数据库,但是我不能修改它。 ``我需要从表t_major中获取一条代码为'5000154130'和编号为'03719552'的记录。

从Navicat中,我发现代码和数字的类型都是 VARCHAR 。在Navicat中,代码和数字的值是'5000154130'和'03719552',但是在我导出记录后,该值更改为“ NTAwMDE1NDEzMAA =”和“ MDM3MTk1NTMA”。

原始插入sql是"INSERT INTO "main"."t_major" ("code","number",...) VALUES(X'5000154130',X'03719552',...);"。此X表示 BLOB

以下所有sql都无法获得结果。

  

无效的SQL

SELECT * FROM t_major WHERE code='5000154130' and number='03719552';
SELECT * FROM t_major WHERE code=hex('5000154130') and hex(number='03719552');
SELECT * FROM t_major WHERE code='5000154130' and number LIKE '03719552';

只有这样才能起作用。

SELECT * FROM t_major WHERE code LIKE '%5000154130%' and number LIKE '%03719552%';

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

https://www.sqlite.org/datatype3.html基本读物,用于了解Sqlite的工作原理。您的问题告诉我您还没有阅读。

  

我发现代码和数字的类型都是VARCHAR

Sqlite没有VARCHAR类型;当在列定义中使用该字段时,将其视为具有TEXT相似性,因为其中包含字符串“ CHAR”。但是您要将BLOB插入表中。不论列的亲和力如何,Sqlite在将其存储在表中时都不会将其转换为任何其他类型。

在前三个SELECT中,您将使用X'5000154130'将表('5000154130')中的blob与文本值(=)进行比较。这种比较永远不会是真的:

从文档中(已添加强调):

  

比较结果取决于操作数的存储类别,并遵循以下规则:

     
      
  • 具有存储类NULL的值被认为小于任何其他值(包括具有存储类NULL的另一个值)。

  •   
  • INTEGER或REAL值小于任何TEXT或BLOB值。将一个INTEGER或REAL与另一个INTEGER或REAL进行比较时,将执行数值比较。

  •   
  • TEXT值小于BLOB值。比较两个TEXT值时,将使用适当的整理顺序来确定结果。

  •   
  • 比较两个BLOB值时,使用memcmp()确定结果。

  •   

您的第四个人...也不应该匹配任何内容。它不在我的测试中。即使在LIKE的情况下,即使sqlite将blob视为文本,所比较的值也不匹配(blob X'0102'是字节0x01 0x02,字符串{{1} }是字节'0102'


基本上,如果要将这些值视为字符串,请不要将其作为斑点插入。如果您无法控制,请通过将记录与适当的Blob(而不是字符串)进行比较来查找记录。


编辑:

我不知道您所说的导出记录是什么意思,但是0x30 0x31 0x30 0x32 string NTAwMDE1NDEzMAA=的Base64编码({ {1}}是 blob '5000154130')的Base64编码。