SQL服务器选择更新

SQL服务器选择更新

问题描述:

我苦苦寻找SQL服务器更换为select for update的作品。SQL服务器选择更新

我有一个包含其用于下一个定单编号的列的主表。应用程序在此行上执行从更新中进行的选择,读取当前值(锁定时)将此值添加一个值,然后更新该行,然后使用收到的数字。这个过程完全适用于我尝试过的所有数据库,但是对于似乎没有任何选择专用数据的过程的SQL Server。

我怎样做一个锁定的读取和像从序列表中的下一个订单号更新为SQL服务器?

顺便说一句,我知道我可以使用的东西像IDENTITY的cols和东西,要做到这一点,但在这种情况下,我必须从这个现有列读取。获得价值并加以利用,并以安全锁定的方式进行操作,以避免2名用户获得相同的价值。

更新::

谢谢你,对于这种情况下的工作:)

DECLARE @Output char(30) 

UPDATE scheme.sysdirm 
SET @Output = key_value = cast(key_value as int)+1 
WHERE system_key='OPLASTORD' 

SELECT @Output 

我有另外一个地方,我做同样的事情。我也读取并锁定了股票记录。

SELECT STOCK 
FROM PRODUCT 
WHERE ID = ? FOR UPDATE. 

我然后做一些验证和做

UPDATE PRODUCT SET STOCK = ? 
WHERE ID=? 

我不能只使用上面的方法在这里,作为值我更新是基于我的事情从我读的股票做。但我需要确保在我这样做的时候没有其他人能够囤积股票。再次,容易在其他数据库的SELECT FOR UPDATE ...有没有一个SQL Server的解决方法? :)

+1

你能后的现有代码?我可能是错的,但你可能只是想做到这一点:'UPDATE表SET字段=字段+ 1 WHERE东西' – jazzytomato 2014-09-26 09:32:29

你可以简单的做一个UPDATE也读出新的价值到SQL Server变量:

DECLARE @Output INT 

UPDATE dbo.YourTable 
SET @Output = YourColumn = YourColumn + 1 
WHERE ID = ???? 

SELECT @Output 

因为它是一个原子UPDATE声明,这是对并发性问题(安全的,因为只有一个连接可以在任何时候获得更新锁定)。想要同时获得递增值的潜在第二个会话必须等到第一个会话完成,从而获得表中的下一个值。

+0

谢谢你。在这个例子中很有用。我有一个更棘手的一个(编辑原始帖子)这是再次简单与SELECT FOR UPDATE,但不是那么肯定你的解决方案适用于那个? – user1667016 2014-09-26 10:37:58

你可以使用UPDATE语句的OUTPUT子句的替代,虽然这会插入到表变量。

Create table YourTable 
(
    ID int, 
    YourColumn int 
) 

GO 

INSERT INTO YourTable VALUES (1, 1) 
GO 


DECLARE @Output TABLE 
( 
    YourColumn int 
) 

UPDATE YourTable 
SET YourColumn = YourColumn + 1 
OUTPUT inserted.YourColumn INTO @Output 
WHERE ID = 1 

SELECT TOP 1 YourColumn 
FROM @Output 

****编辑 如果你想确保没有人可以更改数据您已经阅读后,您可以使用可重复的读取。您应该意识到,您所做的任何表的读取都将被锁定以进行更新(悲观锁定)并可能导致死锁。您也可以在交易中起诉SELECT ... FROM TABLE (UPDLOCK)提示。

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ 
BEGIN TRANSACTION 

SELECT STOCK 
FROM PRODUCT 
WHERE ID = ? 


..... 
... 

UPDATE Product 
SET Stock = nnn 
WHERE ID = ? 

COMMIT TRANSACTION