1

SequenceId是一个自动递增的标识列,但不是主键。

我想要发生的是,当更新一行时,SequenceId将其设置为下一个可用值,例如:

_____________________
| SequenceId | Name |
| 1          | John |
| 2          | Jane |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

将 John 更新为 Jack。SequenceId设置为下一个可用的标识值。

_____________________
| SequenceId | Name |
| 3          | Jack |
| 2          | Jane |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

SQL Server 可以做到这一点吗?如果没有,还有什么替代方案?

4

3 回答 3

6

我不认为你可以,至少不容易或干净。为什么不使用ROWVERSION列?每次将行更新为数据库中新的唯一递增值时,都会更新 ROWVERSION 列。如果要对其进行索引,可以创建一个计算列,将其转换为 bigint。缺点是时间戳是数据库范围的,因此如果您有多个使用它们的表,则可能会跳过数字。

小提琴

create table TestRowVersion (
    Id int primary key,
    Name varchar(20),
    BinaryRowVersion ROWVERSION,
    IntegerRowVersion as convert(BIGINT, BinaryRowVersion)
)   

create index IDX_TestRowVersion on TestRowVersion (IntegerRowVersion)

insert into TestRowVersion (Id, Name) values (1, 'Alvin')
insert into TestRowVersion (Id, Name) values (2, 'Betsy')
insert into TestRowVersion (Id, Name) values (3, 'Charles')
select * From TestRowVersion
update TestRowVersion set Name = 'Frank' where Id = 2
select * From TestRowVersion

[编辑] - 更新为使用 RowVersion,因为 Timestamp 已弃用

于 2012-08-20T05:06:14.610 回答
1

我想要发生的是,当更新一行时,SequenceId 被设置为下一个可用值......

这还不够,您还想更新序列生成器,因此下一个插入的值将是正确的。

如果您使用的是 MS SQL Server 2012,则可以显式使用序列对象,而不是隐式 IDENTITY。这允许您在没有 INSERT 的情况下生成下一个序列号,如下所示:

CREATE SEQUENCE MySquence AS INT START WITH 0;

CREATE TABLE MyTable (
    SequenceId INT DEFAULT (NEXT VALUE FOR MySquence),
    Name VARCHAR(50) PRIMARY KEY
);

INSERT INTO MyTable (Name) VALUES ('John');
INSERT INTO MyTable (Name) VALUES ('Jane');

SELECT * FROM MyTable;

    SEQUENCEID  NAME
    1           Jane
    0           John

UPDATE
    MyTable SET SequenceId = NEXT VALUE FOR MySquence,
    Name = 'Jack'
WHERE Name = 'John';

SELECT * FROM MyTable;

    SEQUENCEID  NAME
    2           Jack
    1           Jane

[SQL 小提琴]


在旧版本中,您可以通过使用单独的表来模拟序列,其中包含单个 IDENTITY 列,然后:

  • 在该表中插入一个新行并使用INSERT..OUTPUT(或@@IDENTITY)获取生成的自动递增数字,
  • 然后您可以立即删除该行以节省存储空间。

或者,如果您不关心任何参照完整性,您可以通过删除和插入来“更新”该行。

于 2012-08-20T16:46:26.557 回答
0

这应该工作...

SET IDENTITY_INSERT [table] ON

UPDATE [table]
SET Name = 'some name',
    SequenceId = MAX(SequenceId) + 1
WHERE ID = 123

SET IDENTITY_INSERT [table] OFF
于 2012-08-20T03:44:00.860 回答