Поделиться через


rowversion (Transact-SQL)

Это тип данных, который представляет собой автоматически сформированные уникальные двоичные числа в базе данных. Тип данных rowversion используется в основном в качестве механизма для отметки версий строк таблицы. Размер при хранении составляет 8 байт. Тип данных rowversion представляет собой увеличивающееся значение, которое не сохраняет дату или время. Тип данных datetime2 используется для записи даты или времени.

Замечания

Каждая база данных имеет счетчик, который увеличивается при каждой операции вставки или обновления в таблице, содержащей столбец типа rowversion в базе данных. Этот счетчик типа rowversion используется для работы с базами данных. Происходит отслеживание относительного времени базы данных, а не действительного времени, которое может быть связано с часами. В таблице может быть только один столбец типа rowversion. Каждый раз при изменении или вставке строки, содержащей столбец типа rowversion, значение увеличенной rowversion вставляется в столбец типа rowversion. Из-за этого свойства столбец типа rowversion нежелательно использовать в ключе, особенно в первичном ключе. Любое обновление, сделанное в строке, изменяет значение rowversion и значение ключа. Если столбец является первичным ключом, старое значение ключа больше недействительно и внешние ключи, ссылающиеся на старое значение, становятся недействительными. Если на таблицу ссылается динамический курсор, все обновления изменяют положение строк в курсоре. Если столбец является ключом индекса, все обновления в строках данных также приводят к обновлению индекса.

Тип данных timestamp является синонимом типа данных rowversion и подчиняется правилам поведения синонимов типа данных. В инструкциях языка DDL используйте по возможности тип данных rowversion вместо timestamp. Дополнительные сведения см. в разделе Синонимы типов данных (Transact-SQL).

Тип данных Transact-SQLtimestamp отличается от типа данных timestamp, определенного в стандарте ISO.

ПримечаниеПримечание

Синтаксис 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 находится в списке SELECT, могут быть сформированы повторяющиеся значения rowversion. Использовать тип данных rowversion таким образом не рекомендуется.

Столбец типа rowversion, который не может принимать значение NULL, семантически эквивалентен столбцу типа binary(8). Столбец типа rowversion, допускающий значения NULL, семантически эквивалентен столбцу типа varbinary(8).

Столбец типа rowversion можно использовать, чтобы определить, было ли произведено изменение какого-либо значения в строке с момента ее последнего считывания. При произведении любых изменений в строке значение rowversion будет обновлено. Если в строке не было никаких изменений, значение rowversion будет таким же, как и при предыдущем считывании. Для получения текущего значения 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 таблицы без отправки повторного запроса в таблицу MyTes.

Ниже приведен тот же пример с использованием синтаксиса 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;