rowversion (Transact-SQL)

這是顯示在資料庫內自動產生的唯一二進位數字的資料類型。rowversion 通常用來做為版本戳記資料表資料列的機制。儲存體大小是 8 位元組。rowversion 資料類型只是會遞增的數字,因此不會保留日期或時間。若要記錄日期或時間,請使用 datetime2 資料類型。

備註

每個資料庫都有一個計數器,會針對在資料庫內包含 rowversion 資料行的資料表所執行的每個插入或更新作業而累加。這個計數器是資料庫資料列版本。這會追蹤資料庫內的相對時間,而不是可關聯於時鐘的實際時間。資料表只能有一個 rowversion 資料行。每次修改或插入含 rowversion 資料行的資料列時,都會在 rowversion 資料行中插入累加的資料庫資料列版本值。這個屬性會使 rowversion 資料行不適合做為索引鍵 (尤其是主索引鍵) 的候選項。資料列的任何更新都會變更資料列版本值,因而會變更索引鍵值。如果資料行在主索引鍵中,舊的索引鍵值便不再有效,參考舊值的外部索引鍵也不再有效。如果動態資料指標參考資料表,所有更新都會變更資料列在資料指標中的位置。如果資料行在索引鍵中,資料列的所有更新也會產生索引的更新。

timestamp 是 rowversion 資料類型的同義字,遵照資料類型同義字的行為。在 DDL 陳述式中,請盡可能利用 rowversion 來取代 timestamp。如需詳細資訊,請參閱<資料類型同義字 (Transact-SQL)>。

Transact-SQLtimestamp 資料類型不同於 ISO 標準中所定義的 timestamp 資料類型。

[!附註]

timestamp 語法已被取代。未來的 Microsoft SQL Server 版本將移除這項功能。請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。

在 CREATE TABLE 或 ALTER TABLE 陳述式中,您不需要指定 timestamp 資料類型的資料行名稱,例如:

CREATE TABLE ExampleTable (PriKey int PRIMARY KEY, timestamp);

如果您沒有指定資料行名稱,SQL Server Database Engine 會產生 timestamp 資料行名稱;不過,rowversion 同義字不會遵照這個行為。當您使用 rowversion 時,您必須指定一個資料行名稱,例如:

CREATE TABLE ExampleTable2 (PriKey int PRIMARY KEY, VerCol rowversion) ;

[!附註]

您可以利用 SELECT INTO 陳述式來產生重複的 rowversion 値,rowversion 資料行在 SELECT 清單中。我們不建議您利用這個方式來使用 rowversion。

不可為 Null 的rowversion 資料行,語意等於 binary(8) 資料行。可為 Null 的 rowversion 資料行,語意等於 varbinary(8) 資料行。

您可以利用資料列的 rowversion 資料行來輕易判斷上次讀取資料列之後,資料列中的任何值是否有任何改變。如果資料列有了任何改變,就會更新資料列版本值。如果資料列沒有任何改變,資料列版本值就與先前讀取時相同。若要傳回資料庫目前的資料列版本值,請使用 @@DBTS

您可以將 rowversion 資料行加入至資料表,以確保能在多個使用者同時更新資料列時維護資料庫的完整性。您可能也想在不必重新查詢資料表的情況下,知道更新了多少資料列以及更新了哪些資料列。

例如,假設您要建立名為 MyTest 的資料表。您利用執行下列的 Transact-SQL 陳述式,在資料表中擴展一些資料。

CREATE TABLE MyTest (myKey int PRIMARY KEY
    ,myValue int, RV rowversion);
GO 
INSERT INTO MyTest (myKey, myValue) VALUES (1, 0);
GO 
INSERT INTO MyTest (myKey, myValue) VALUES (2, 0);
GO

然後可以使用下列的範例 Transact-SQL 陳述式,在更新期間將開放式並行存取控制項實作於 MyTest 資料表。

DECLARE @t TABLE (myKey int);
UPDATE MyTest
SET myValue = 2
    OUTPUT inserted.myKey INTO @t(myKey) 
WHERE myKey = 1 
    AND RV = myValue;
IF (SELECT COUNT(*) FROM @t) = 0
    BEGIN
        RAISERROR ('error changing row with myKey = %d'
            ,16 -- Severity.
            ,1 -- State 
            ,1) -- myKey that was changed 
    END;

myValue 代表您上次讀取資料列時,該資料列的 rowversion 資料行値。此値必須由實際的 rowversion 値取代。實際 rowversion 値的範例是 0x00000000000007D3。

您也可以將範例 Transact-SQL 陳述式放入交易中。您可藉由在交易的範圍中查詢 @t 變數來擷取資料表已更新的 myKey 資料行,而不必重新查詢 MyTest 資料表。

下列為使用 timestamp 語法的相同範例:

CREATE TABLE MyTest2 (myKey int PRIMARY KEY
    ,myValue int, TS timestamp);
GO 
INSERT INTO MyTest2 (myKey, myValue) VALUES (1, 0);
GO 
INSERT INTO MyTest2 (myKey, myValue) VALUES (2, 0);
GO
DECLARE @t TABLE (myKey int);
UPDATE MyTest2
SET myValue = 2
    OUTPUT inserted.myKey INTO @t(myKey) 
WHERE myKey = 1 
    AND TS = myValue;
IF (SELECT COUNT(*) FROM @t) = 0
    BEGIN
        RAISERROR ('error changing row with myKey = %d'
            ,16 -- Severity.
            ,1 -- State 
            ,1) -- myKey that was changed 
    END;