无法通过BLOB列查询SQLite

本文关键字:查询 SQLite BLOB | 更新日期: 2023-09-27 18:21:47

我正试图通过一个SHA256哈希的blob列来查询SQLite表。

CREATE TABLE Articles (HASH BLOB(32) PRIMARY KEY, Article TEXT)

像这样的查询不会返回任何内容:

SELECT * FROM Articles WHERE HASH = ?
-- the parameter is bound using sqlite3_bind_blob, not to use literals

我用C#制作了这个小程序,它创建了表,还插入了一行进行尝试。

using System;
using System.Linq;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Security.Cryptography;
// using lib;
public class Program {
    static int Main(string[] args) 
    {
        // Console.WriteLine(sqlite3.LibVersion);
        byte[] qHash;
        string qArticle = "Lorem ipsum dolor sit amet";
        using (var hashAlgorithm = new SHA256CryptoServiceProvider ()) {
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(qArticle);
            qHash = hashAlgorithm.ComputeHash(bytes);
        }
        var con = new SQLiteConnection ("Data Source=test.sqlite");
        con.Open();
        try {
            var create = new SQLiteCommand ("CREATE TABLE Articles (HASH BLOB(32) PRIMARY KEY, Article TEXT)", con);
            create.ExecuteNonQuery();
            var insert = new SQLiteCommand ("INSERT INTO Articles (HASH, Article) VALUES (?, ?); SELECT last_insert_rowid();", con);
            var insertParam0 = new SQLiteParameter(DbType.Binary);
            insertParam0.Value = qHash;
            insert.Parameters.Add(insertParam0);
            var insertParam1 = new SQLiteParameter(DbType.String);
            insertParam1.Value = qArticle;
            insert.Parameters.Add(insertParam1);
            object insert_result = insert.ExecuteScalar();
            var insert_rowid = (long)insert_result; 
        } catch { } // silently fail if exists usually
        var query = new SQLiteCommand ("SELECT * FROM Articles WHERE HASH = @hash", con);
        var param = new SQLiteParameter ("@hash", DbType.Binary);
        param.Value = qHash;
        query.Parameters.Add(param);
        using (SQLiteDataReader reader = query.ExecuteReader()) {
            while (reader.NextResult()) {
                var hash = new byte[32];
                long hashLen = reader.GetBytes(0, 0, hash, 0, 32);
                string article = reader.GetString(1);
                Console.WriteLine("HASH: {0}; Article: {1}", 
                    hash == null ? null : BitConverter.ToString(hash).Replace("-", ""), 
                    article
                );
            }
        }
        con.Close();
        return 0;
    }
}

但是reader没有结果。是否根本不支持查询BLOB列
还有什么事困扰着我吗?

无法通过BLOB列查询SQLite

这里的问题是通过发现Read用于而解决的

while (reader.Read()) { }

循环,而NextResult用于

do { } while (reader.NextResult());

循环。

然而,最初的问题是,在我的真实项目中,我使用BLOB Hex Editor中的SQLiteStudio(SQLite 3.7.16.1)创建了数据库;混淆了System.Data.SQLite库(使用SQLite 3.8.2)。

现在通过使用程序本身创建数据库也解决了的初始问题

  • C#中的SQLite使用.GetBytes抛出"InvalidCastException"
    我用(byte[])reader[0]处理过它,它也返回了正确的字节,但在SELECT中没有被限定,既没有参数也没有文字

也就是说,不要混用SQLite版本,甚至不要快速尝试。我非常努力,甚至为sqlite3_*启动了一个带有DllImport绑定的UnmanagedLibrary,结果发现这不是问题所在。