2010-02-17 40 views
4

我在SQL Server中有一個表tblMain。有一個觸發器,當一行更改時,它基本上從tblMain中執行一個SELECT *,並將更改後的行插入到tblHistory中。 tblHistory是tblMain的副本(只有更高),它有一個額外的字段用於唯一的ID。我最近添加了TimeStamp類型的字段(我現在明白這個字段已被棄用,但我會在稍後處理)以避免Microsoft Access 2007中的寫入衝突問題。什麼類型的SQL Server用作可寫時間戳?

顯然,觸發器會複製每個字段tbl主要是歷史。它正在做一個Select *。但是,如果我在歷史記錄表中放入一個timeStamp類型的字段以接收來自tblMain的字段,觸發器將顯然失敗。我應該在歷史表中使用什麼類型的接受TimeStamp源?

回答

4

從文檔:

甲非空時間戳列在語義上等同於二進制(8)柱。可空的時間戳列在語義上等同於varbinary(8)列。

這工作:

-- //Main table, with TIMESTAMP column 
CREATE TABLE Main (id INT, TIMESTAMP) 

-- //Some values 
INSERT Main VALUES (8, DEFAULT) 
INSERT Main VALUES (4, DEFAULT) 
INSERT Main VALUES (2, DEFAULT) 
INSERT Main VALUES (7, DEFAULT) 
INSERT Main VALUES (0, DEFAULT) 

-- //See the values 
SELECT * FROM Main 

-- //History table 
-- //with VARBINARY(8) to store a nullable TIMESTAMP 
CREATE TABLE History (id INT, ts VARBINARY(8)) 

-- //Populate History table 
INSERT History 
SELECT * FROM Main 

-- //See the values 
SELECT * FROM History 
+0

確實是一個非常好的答案。謝謝! – Knox

+0

剛剛嘗試過。像冠軍一樣工作! – Knox

3

TIMESTAMP列的類型正在重新命名,基本上,使用SQL Server 2008和更高版本,它將被稱爲ROWVERSION而不是 - 它不會消失,只是有一個新的名稱。

現在,TIMESTAMP列確實是不可寫的 - 基本上,在觸發器中,您需要執行一個INSERT語句,其中列出了您要編寫的所有列 - 並省略了TIMESTAMP。

TIMESTAMP/ROWVERSION是你最好的選擇 - 只有這種類型的列保證始終是唯一的,對於每個後續插入,總是不斷增加。任何與DATE相關的列都可能有重複項(在SQL Server 2005中,DATETIME的準確性爲3.33毫秒 - 所以你肯定可以有重複項)。

您可能希望將TIMESTAMP用於準確性和唯一性以及DATETIME用於人類可讀性的組合。 TIMESTAMP由SQL Server自動處理,對於LastModifiedDate DATETIME,您可以定義DEFAULT CONSTRAINTGETDATE(),以便對於每個插入,都會記錄當前的日期/時間。

+0

感謝如何處理這個前進的信息。 – Knox

0

在觸發器中,您可以執行此操作,該操作只會插入受影響的行,並且比解析原始表更快以查找已更改的內容。

INSERT INTO tblHistory 
     (col1, col2, ...) 
    SELECT 
     col1, col2, ... 
     FROM INSERTED 
+0

我不想將列名放在觸發器中,因爲它們會不時發生變化,而且這更像是維護問題。 – Knox

+0

如何處理歷史表中表格的變化列?另外,我希望你在觸發器中使用INSERTED表。 –