2015-05-28 76 views
1

我重構了一個表,它將元數據和數據都存儲到兩個表中,一個用於元數據,另一個用於數據。這允許元數據被有效查詢。Sqlite:是否更新插入觸發原子中的兩個表?

我還使用sqlite的插入,更新和刪除觸發器,使用原始表格的列創建了可更新視圖。這允許調用需要數據和元數據的代碼保持不變。

的INSERT和UPDATE觸發器寫每個傳入行作爲兩行 - 一個元數據表和一個數據表,如下所示:

// View 
CREATE VIEW IF NOT EXISTS Item as select n.Id, n.Title, n.Author, c.Content 
FROM ItemMetadata n, ItemData c where n.id = c.Id 

// Trigger 
CREATE TRIGGER IF NOT EXISTS item_update 
INSTEAD OF UPDATE OF id, Title, Author, Content ON Item 
BEGIN 

UPDATE ItemMetadata 
SET Title=NEW.Title, Author=NEW.Author 
WHERE Id=old.Id; 

UPDATE ItemData SET Content=NEW.Content 
WHERE Id=old.Id; 

END; 

問題:

  • 是更新到ItemMetadata和ItemData表原子?在第二次更新完成之前,讀者是否有機會看到第一次更新的結果?
  • 本來我有WHERE子句是WHERE rowid=old.rowid,但這似乎會導致隨機問題,所以我將它們更改爲WHERE Id=old.Id。原始版本基於我找到的教程代碼。但是在思考之後,我想知道sqlite是如何產生舊的rowid的 - 畢竟這是跨多個表的視圖。 sqlite傳遞給更新觸發器的是什麼rowid,並且是我第一次編碼它的WHERE子句有問題?

回答

1

documentation說:

不可更改的數據庫進行事務之外,。任何改變數據庫的命令(基本上,除了SELECT之外的任何SQL命令)都會自動啓動一個事務,如果這個事務還沒有生效。

觸發器中的命令被視爲觸發觸發器的命令的一部分。 因此,觸發器中的所有命令都是事務的一部分,並且是原子的。 (可用)rowid

+0

謝謝。在視圖中有沒有關於rowid的官方文檔? – bright

+0

正如你在問題中提到的那樣,沒有可以在視圖中使用的'rowid'。 SQLite允許訪問這個列是一個錯誤,但它保持向後兼容性。 –