使用 rowversion 更新行时出现异常?
Exception when updating row with rowversion?
我有一个 table 看起来像这样:
CREATE TABLE [dbo].[akut_prioritering]
(
[behandling_id] [int] NOT NULL,
[akutstatus] [int] NOT NULL,
[nasta_dag] [bit] NOT NULL,
[sort_order] [bigint] NOT NULL,
[rowversion] [timestamp] NOT NULL,
CONSTRAINT [XPKakut_prioritering]
PRIMARY KEY CLUSTERED ([behandling_id] ASC)
) ON [PRIMARY]
然后我有这个存储过程试图更新此 table 中的行:
ALTER PROCEDURE [dbo].[akutlistaSave]
@behandlingSortOrder dbo.akutlista_sortorder_tabletype READONLY
AS
BEGIN
SET NOCOUNT ON;
DECLARE @behandlingId INT;
DECLARE @sortOrder BIGINT;
DECLARE @rowversion ROWVERSION;
DECLARE sortOrderCursor CURSOR LOCAL SCROLL STATIC FOR
SELECT behandling_id, sort_order FROM @behandlingSortOrder
OPEN sortOrderCursor
BEGIN TRAN
FETCH NEXT FROM sortOrderCursor INTO @behandlingId, @sortOrder, @rowversion
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(SELECT *
FROM akut_prioritering ap
WHERE ap.behandling_id = @behandlingId
AND ap.rowversion = @rowversion)
BEGIN
UPDATE akut_prioritering
SET sort_order = @sortOrder
WHERE behandling_id = @behandlingId;
END
ELSE
BEGIN
RAISERROR ('Rowversion not correct.', 16, 1);
END
FETCH NEXT FROM sortOrderCursor INTO @behandlingId, @sortOrder, @rowversion
END
CLOSE sortOrderCursor
SELECT
ap.behandling_id, ap.rowversion
FROM
akut_prioritering ap
INNER JOIN
@behandlingSortOrder bso ON ap.behandling_id = bso.behandling_id;
DEALLOCATE sortOrderCursor
END
参数类型如下所示:
CREATE TYPE [dbo].[akutlista_sortorder_tabletype] AS TABLE
(
[behandling_id] [int] NULL,
[sort_order] [bigint] NULL,
[rowversion] [timestamp] NULL
)
当 运行 这个我得到一个 SqlException
:
Cannot insert an explicit value into a timestamp column. Use INSERT with a column list to exclude the timestamp column, or insert a DEFAULT into the timestamp column.
根据我的理解,rowversion
列应该自动更新为新值,在我的情况下没有理由手动设置它。
您不能在 dbo.akutlista_sortorder_tabletype
中设置 rowversion
值,因为它不可更新:它是自动生成的
但是,rowversion
(a.k.a 已弃用 timestamp
)只是一个具有一些特殊规则的 (var)binary(8)。您可以在 dbo.akutlista_sortorder_tabletype
中定义和设置 (var)binary(8) 并在 UPDATE
中进行比较
从第一个开始link
A nonnullable rowversion column is semantically equivalent to a binary(8) column. A nullable rowversion column is semantically equivalent to a varbinary(8) column.
看起来您正在尝试 insert
自定义 table 类型中的 timestamp
值,然后将其传递给您的存储过程。正如您的错误所暗示的那样,您不能 insert
显式 timestamp
值进入 timestamp
列。
您需要找到一种不同的方式来将您的 table 值传递给此存储过程才能工作。
我有一个 table 看起来像这样:
CREATE TABLE [dbo].[akut_prioritering]
(
[behandling_id] [int] NOT NULL,
[akutstatus] [int] NOT NULL,
[nasta_dag] [bit] NOT NULL,
[sort_order] [bigint] NOT NULL,
[rowversion] [timestamp] NOT NULL,
CONSTRAINT [XPKakut_prioritering]
PRIMARY KEY CLUSTERED ([behandling_id] ASC)
) ON [PRIMARY]
然后我有这个存储过程试图更新此 table 中的行:
ALTER PROCEDURE [dbo].[akutlistaSave]
@behandlingSortOrder dbo.akutlista_sortorder_tabletype READONLY
AS
BEGIN
SET NOCOUNT ON;
DECLARE @behandlingId INT;
DECLARE @sortOrder BIGINT;
DECLARE @rowversion ROWVERSION;
DECLARE sortOrderCursor CURSOR LOCAL SCROLL STATIC FOR
SELECT behandling_id, sort_order FROM @behandlingSortOrder
OPEN sortOrderCursor
BEGIN TRAN
FETCH NEXT FROM sortOrderCursor INTO @behandlingId, @sortOrder, @rowversion
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(SELECT *
FROM akut_prioritering ap
WHERE ap.behandling_id = @behandlingId
AND ap.rowversion = @rowversion)
BEGIN
UPDATE akut_prioritering
SET sort_order = @sortOrder
WHERE behandling_id = @behandlingId;
END
ELSE
BEGIN
RAISERROR ('Rowversion not correct.', 16, 1);
END
FETCH NEXT FROM sortOrderCursor INTO @behandlingId, @sortOrder, @rowversion
END
CLOSE sortOrderCursor
SELECT
ap.behandling_id, ap.rowversion
FROM
akut_prioritering ap
INNER JOIN
@behandlingSortOrder bso ON ap.behandling_id = bso.behandling_id;
DEALLOCATE sortOrderCursor
END
参数类型如下所示:
CREATE TYPE [dbo].[akutlista_sortorder_tabletype] AS TABLE
(
[behandling_id] [int] NULL,
[sort_order] [bigint] NULL,
[rowversion] [timestamp] NULL
)
当 运行 这个我得到一个 SqlException
:
Cannot insert an explicit value into a timestamp column. Use INSERT with a column list to exclude the timestamp column, or insert a DEFAULT into the timestamp column.
根据我的理解,rowversion
列应该自动更新为新值,在我的情况下没有理由手动设置它。
您不能在 dbo.akutlista_sortorder_tabletype
中设置 rowversion
值,因为它不可更新:它是自动生成的
但是,rowversion
(a.k.a 已弃用 timestamp
)只是一个具有一些特殊规则的 (var)binary(8)。您可以在 dbo.akutlista_sortorder_tabletype
中定义和设置 (var)binary(8) 并在 UPDATE
从第一个开始link
A nonnullable rowversion column is semantically equivalent to a binary(8) column. A nullable rowversion column is semantically equivalent to a varbinary(8) column.
看起来您正在尝试 insert
自定义 table 类型中的 timestamp
值,然后将其传递给您的存储过程。正如您的错误所暗示的那样,您不能 insert
显式 timestamp
值进入 timestamp
列。
您需要找到一种不同的方式来将您的 table 值传递给此存储过程才能工作。