2012-12-26 19 views
1

我想使用SQLite爲通常從服務器請求數據的.NET應用程序創建脫機緩存。我已經有了數據庫和表定義部分工作正常,並且大部分加載數據也工作得很好。我在測試表中緩存了大約14,000行,數據大部分是正確的。問題是,我似乎無法使System.Data.SQLite包裝保留包含SQL時間戳值的byte[]數據。SQLite blob字段沒有收到參數值

在別的之前,我應該注意到我意識到我可以將時間戳編碼爲別的東西(比如字符串或數字數據),但是我更願意使用本地BLOB功能,如果可能的話。所以我們從那裏開始。

表DDL看起來是這樣的,現在:

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

但是我要指出,我自己也嘗試了TimestampVARBINARYVARBINARY(4000)BINARYGENERAL列類型,在結果沒有差異。

在插入的時候,我產生一個參數化的SQL命令看起來像這樣(很多領域爲清楚起見刪除):

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

參數@Timestamp給出的Binary一個DbType並具有合適的大小,插入的行中的所有其他數據看起來都不錯。但由於某種原因,Timestamp被留空。爲什麼會這樣呢?

該值可驗證地爲byte[8]與預期內容。實際上,如果我將列類型更改爲具有字符串相關性並給它一個DbType.String,則該列將存儲「System.Byte []」。

列的值爲空的事實是確定的,首先通過使用SQLite數據庫瀏覽器打開數據庫文件並查找,其次是因爲使用(SELECT MAX(Timestamp) FROM Accounts)在第二個表中設置列使字段爲空,根據文檔發生當且僅當每行的時間戳爲空。

那麼我會錯過什麼?

**編輯**

注意所有:這是SQLite,不是SQL CE。有些迴應似乎混淆了兩者。

+0

爲什麼要將@Timestamp值作爲Blob存儲,爲什麼不把它作爲TimeStamp或DateTime存儲? – MethodMan

+0

什麼是'1'在選擇1從帳戶在查詢...我認爲查詢本身是錯誤的邏輯..! –

+0

@DJKRAZE請參閱[這裏](http://www.sqlite.org/datatype3.html)瞭解SQLite數據類型。即使在SQLCE中,Timestamp也不起作用(因爲時間戳是服務器時間戳,所以它需要是「二進制(8)」)。值是一個SQL'TIMESTAMP' /'ROWVERSION',所以它與DateTime數據無關。 –

回答

2

嗯,這真的很奇怪。當我意識到SQLite數據庫瀏覽器對我說謊時 - 我在截取二進制數據0x0處,這是我所有時間戳值的第一個字節,並將這些字段報告爲空,我獲得了突破。在嘗試插入隨機字節數據而不是時間戳後,我發現了這一點,在這一點上,我看到數據通過GUI顯示。顯然它將數據視爲以空字符結尾的字符串,並且我一開始並不知道它太天真了。

現在,我一直使用SQLite數據庫瀏覽器作爲代理來調試問題(當我嘗試讀取時間戳記值時,出現DBNulls)。但是當我回頭看看我是否仍然從System.Data.SQLite包裝中獲取DBNull時,我發現代碼在僅使用原始時間戳數據的情況下運行時,不再生成DBNulls。在某些時候,代碼已經開始工作 - 我只是沒有注意到,因爲我愚蠢地依靠GUI來顯示數據。

奇怪的是,我試着回顧我的步驟,撤消了我所做的事情,試圖找出具體解決問題的具體方法。但是現在我無法重現原來的錯誤,儘管它最初是完全一致的(事實是我無法繞過它,促使我首先使用GUI)。但是我沒有檢查每個破解版本到源代碼控制中,所以在這一點上我真的不知道問題是什麼。

無論如何,這個故事至少有一個道理,就是說,如果你不確定它的能力,就不要相信GUI。很難說我已經有了多久的工作代碼,只是不知道它。