【问题标题】:Querying SQLite by BLOB column not possible?无法通过 BLOB 列查询 SQLite?
【发布时间】:2014-09-13 09:22:25
【问题描述】:

我正在尝试通过一个 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 应该可以正常工作(example 使用 blob 文字)。插入是否有效,即数据库是否包含该行?
  • 当然,该行存在;我不想使用文字(这也不起作用......),因为十六进制转换、字符串连接、转义等。
  • HELL 它适用于reader.Read 而不是.NextResult 为什么。我应该关闭这个 Q 吗?
  • @metadings 将其作为答案发布并在允许时接受。将来会帮助其他人。

标签: c# system.data.sqlite


【解决方案1】:

这里的问题是通过发现Read被用在a中解决的

while (reader.Read()) { }

循环,而NextResult用于

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

循环。

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

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

所以说,不要混合 SQLite 版本,甚至不要快速尝试一些东西。我非常努力,甚至为 sqlite3_* 启动了一个带有 DllImport 绑定的 UnmanagedLibrary,只是发现这不是问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多