使用TOP和WHERE更新一行 In SQL, you can use the UPDATE statement to modify the values in a specific row of a table. The TOP clause allows you to specify the number of rows to update, while the WHERE clause helps you specify the criteria for selecting the row(s)

26 浏览
0 Comments

使用TOP和WHERE更新一行 In SQL, you can use the UPDATE statement to modify the values in a specific row of a table. The TOP clause allows you to specify the number of rows to update, while the WHERE clause helps you specify the criteria for selecting the row(s)

我计划使用仅使用SQL Server表格来实现一种工作队列,每次只将一行分配给一个用户。我计划采用常见的UPDATE SET .. WHERE ..方法,就像在这个问题中提出的建议一样:\nhttps://stackoverflow.com/a/9241466\n以下是相关部分的引用:\n

;WITH CTE AS 
( 
    SELECT TOP 100 * 
    FROM T1      
    ORDER BY F2 
) 
UPDATE CTE SET F1='foo'

\n为了确保只有一个用户可以编辑一行,我将包含一个额外的属性UserId,并在WHERE子句中检查NULL。\n

;WITH CTE AS 
( 
    SELECT TOP 5 * 
    FROM T1
    WHERE UserId IS NULL      
    ORDER BY F2 
) 
UPDATE CTE SET UserId = @userid

\n完成语句后,我将从数据库中SELECT受影响的行。\n然而,我可能还想在WHERE子句中包含一些额外的属性,以及一些额外的排序。\n如果WHERE包含在CTE中,UPDATE将锁定行吗?\n我的问题是,换个说法,UPDATE是否仍然会锁定行,还是由于竞争问题,两个并发运行的语句可能会覆盖UserId?

0
0 Comments

在上述内容中,出现了一个问题:在同时更新同一行的情况下,第二个查询需要等待第一个查询完成才能正确过滤数据。这个问题的原因是两个查询都按照相同的标准进行排序,并且第二个查询需要对第一行进行授予权限才能进行更新。解决方法是等待第一个查询提交后,第二个查询就可以读取数据并对其他行进行锁定。

为了模拟这个问题,首先创建了一个名为"StackOverflow"的表,然后插入了5行数据,其中"UserID"列的值都为空。接下来,在两个不同的查询窗口中运行了相同的代码,代码中使用了CTE(公共表表达式)来选择前两行数据,并根据条件进行排序。然后,对选择的行进行了更新,第一个查询将"UserID"设置为1,第二个查询将"UserID"设置为2。在查询的过程中,使用了"sys.dm_tran_locks"视图来查看锁定信息。

通过观察锁定信息,可以发现第二个查询需要等待第一个查询完成后才能继续执行。当第一个查询提交后,第二个查询才能读取数据并对其他行进行锁定。最终,表中的数据被正确更新为:

+----+-------+

| ID | UserID |

+----+-------+

| 1 | 1 |

| 2 | 2 |

| 3 | NULL |

| 4 | NULL |

| 5 | NULL |

+----+-------+

因此,在这种情况下,不需要担心两个语句会覆盖数据。

0