同时冲突的更新查询

时间:2014-05-20 17:46:32

标签: sql sql-server

我觉得这是一个相当普遍的情况,但我找不到直接解决这个问题的解决方案。

考虑下表:

Username           HatSize

Tim                4  
Julie              3   
Mark               3
Susan              4

假设我错误地输入了“Hat Size”列中的值。我想更新表,以便HatSize为4变为3,HatSize为3变为4(有效地交换3和4的值),如下表所示:

Username           HatSize

Tim                3  
Julie              4   
Mark               4
Susan              3

如果我要运行一个简单的更新查询:

UPDATE table SET HatSize = '3' WHERE HatSize = '4'
UPDATE table SET HatSize = '4' WHERE HatSize = '3'

它只会在HatSize列4中生成所有值。我认为将其作为事务运行,但我似乎无法找到任何暗示运行上述并发更新查询的内容可以正常工作的内容。

我意识到我可以使用中间值,但有更优雅的方式来实现这样的目标吗?

3 个答案:

答案 0 :(得分:1)

UPDATE table 
   SET HatSize = CASE 
                      WHEN HatSize = '3' THEN '4'
                      WHEN HatSize = '4' THEN '3'
                 END

SQL FIDDLE

答案 1 :(得分:0)

我知道一种处理冲突变化的技术,称为乐观并发。

您可以在表格中创建一个Timestamp列,每次更新行时都会自动更改为当前时间。

假设您有一个客户端从该表的一行中提取信息,更改了其中的一部分,并尝试将行值写回数据库。在更新查询的“WHERE”子句中,仅更新时间戳等于客户端最初引入的时间戳的行。客户端的时间戳值应与当前行中的值相同。如果不是,则更新查询将影响0行。这是应该抛出并发异常的时候。

然后,您将捕获异常,更新尝试进行更改的客户端的值,并通知他们其他人更新了该记录。

答案 2 :(得分:0)

你使用什么样的SQL?我会使用temp来跟踪其中一个值的所有记录。在MS SQL中:

INSERT Username
INTO #tmp
FROM TableName
WHERE HatSize='3'

UPDATE TableName SET
   HatSize=3
WHERE HatSize=4

UPDATE TableName SET
   HatSize=4
WHERE Usernaem IN (SELECT UserName FROM #tmp)