INSERT stuff
SET computed = 'working'
WHERE id = (SELECT max(id) from STUFF WHERE x = y)
我想在 SQL Server 2005 SP 1 中使这个语句原子化。
有没有办法在不修改隔离级别的情况下做到这一点?
我需要模拟插入以标识列作为 pk 的表。我当前的表没有像 pk 一样的 Identity 字段,但它需要像它一样工作。所以我需要获取伪 ID 字段的最大值并添加 1,然后插入下一行。
INSERT stuff
SET computed = 'working'
WHERE id = (SELECT max(id) from STUFF WHERE x = y)
我想在 SQL Server 2005 SP 1 中使这个语句原子化。
有没有办法在不修改隔离级别的情况下做到这一点?
我需要模拟插入以标识列作为 pk 的表。我当前的表没有像 pk 一样的 Identity 字段,但它需要像它一样工作。所以我需要获取伪 ID 字段的最大值并添加 1,然后插入下一行。
To lock the value down, one way is to to use SERIALIZABLE isolation level.
DECLARE @id int;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRAN
SELECT TOP(1) @id id from STUFF WHERE x = y ORDER BY id DESC;
INSERT stuff (id, ...) VALUES (@id, ...);
COMMIT
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
Make sure to keep it as short as possible.
如果不能添加 IDENTITY 列,是否可以创建另一个包含 IDENTITY 列的表?然后只需插入该表并使用@@IDENTITY 即可插入需要该序列的表中。此技术将为您记住最后一个数字,因此您不会获得任何重复使用的值。
在 SQL Server 2012 之前的版本中,类似的技术用于模拟 Oracle 的序列(与表无关)。
http://www.sqlmag.com/article/tsql3/simulating-oracle-sequences-in-t-sql-code
如果您愿意,您可以随时将这些序列表放入单独的模式中。