SQLite blob字段不接收参数值

时间:2012-12-26 16:45:05

标签: c# sqlite system.data.sqlite

我正在尝试使用SQLite为.NET应用程序创建脱机缓存,该应用程序通常从服务器请求数据。我已经让数据库和表定义部分工作正常,并且在大多数情况下加载数据也工作得很好。我在我的测试表中缓存大约14,000行,数据大部分是正确的。问题是我似乎无法使用System.Data.SQLite包装器来保存包含SQL时间戳值的byte[]数据。

在其他任何事情之前,我应该注意到我意识到我可以将时间戳编码为其他东西(例如字符串或数字数据),但我更愿意使用本机BLOB功能,如果可能的话。那么让我们从那里开始吧。

表DDL现在看起来像这样:

CREATE TABLE Accounts
(
    AccountID Int NOT NULL,
    -- ...
    Timestamp BLOB
)

但是我应该注意到,我还为VARBINARY的列类型尝试了VARBINARY(4000)BINARYGENERALTimestamp,没有区别在结果中。

在插入时,我生成一个参数化的SQL命令,看起来像这样(为清晰起见,删除了很多字段):

INSERT INTO Accounts (AccountID, Timestamp)
SELECT @AccountID, @Timestamp
WHERE NOT EXISTS (SELECT 1 FROM Accounts WHERE AccountID = @AccountID)

参数@Timestamp的{​​{1}}为DbType且大小合适,插入行中的所有其他数据看起来都不错。但由于某种原因,Binary保留为空。为什么会这样?

该值可验证为Timestamp,具有预期内容。实际上,如果我将列类型更改为具有字符串亲和力并将其设为byte[8],则该列将存储“System.Byte []”。

列具有空值的事实是肯定的,首先只需使用SQLite数据库浏览器打开数据库文件并查看,然后第二,因为使用DbType.String在第二个表中设置列会离开该字段null,当且仅当每行的Timestamp为空时,根据文档发生。

那么我还能错过什么?

**编辑**

全部注意:这是SQLite,而不是SQL CE。一些回应似乎使两者混淆。

1 个答案:

答案 0 :(得分:2)

嗯,这真的很奇怪。当我意识到SQLite数据库浏览器对我说谎时,我有一个突破 - 它正在截断0x0处的二进制数据,这是我所有时间戳值的第一个字节,并将这些字段报告为空。我在尝试插入随机字节数据而不是时间戳后发现了这一点,此时我看到数据在GUI中出现。显然,它将数据视为以空字符结尾的字符串,而且我一开始并不知道它是天真的。

现在,我一直在使用SQLite数据库浏览器作为代理来调试问题(当我尝试读取时间戳值时,DBNull就出现了)。但当我回过头来看看我是否仍然从System.Data.SQLite包装器中获取DBNull时,我发现代码在仅使用原始时间戳数据运行时不再生成DBNull。在某些时候代码已经开始工作 - 我没有注意到,因为我愚蠢地依靠GUI来向我显示数据。

奇怪的是,我尝试回顾我的步骤,撤消我要做的事情,试图找出具体解决问题的方法。但是现在我无法重现原始错误,虽然它最初是绝对一致的(我无法绕过它的事实促使我首先使用GUI)!但我还没有将每个破碎的版本检查为源代码控制,所以此时我真的不知道问题是什么。

无论如何,至少有一个故事的道德,如果你不确定它的能力,就不要相信GUI。很难说我已经有多长时间没有工作代码,只是不知道它。