rowversion (Transact-SQL)

Применимо к: даSQL Server (все поддерживаемые версии) ДаБаза данных SQL Azure

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

Комментарии

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

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

Тип данных Transact-SQL timestamp отличается от типа данных 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 при обновлении таблицы. Скрипт использует <myRv> для представления значения rowversion на момент последнего считывания строки. Замените это значение фактическим значением rowversion. Примером фактического значения rowversion является 0x00000000000007D3.

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

В транзакцию можно также ввести эти образцы инструкций Transact-SQL. При запросе переменной @t в области действия транзакции можно получить обновленный столбец myKey таблицы без отправки повторного запроса в таблицу MyTest.

Ниже приведен тот же пример с использованием синтаксиса timestamp. Замените <myTS> фактическим значением 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 = <myTS>;  
IF (SELECT COUNT(*) FROM @t) = 0  
    BEGIN  
        RAISERROR ('error changing row with myKey = %d'  
            ,16 -- Severity.  
            ,1 -- State   
            ,1) -- myKey that was changed   
    END;  

См. также раздел

ALTER TABLE (Transact-SQL)
Функции CAST и CONVERT (Transact-SQL)
CREATE TABLE (Transact-SQL)
Типы данных (Transact-SQL)
DECLARE @local_variable (Transact-SQL)
DELETE (Transact-SQL)
INSERT (Transact-SQL)
MIN_ACTIVE_ROWVERSION (Transact-SQL)
SET @local_variable (Transact-SQL)
UPDATE (Transact-SQL)