sql - 更新+使用(行锁)+ CTE

标签 sql sql-server sql-server-2008 tsql sql-server-2012

我找不到任何有关 T-SQL 语句语法的文档: 我需要对 CTE 结果进行 WITH (ROWLOCK) 更新。

类似于:(因此更新后将是top1000 table1.col2。在对table1的行进行更新期间,语句WITH (ROWLOCK)至关重要)

    ;WITH CTE AS 
    ( 
        SELECT TOP(1000) table1.col2
        FROM  table1 INNER JOIN table2 ON table1.id = table2.id    
    ) 
    UPDATE CTE WITH (ROWLOCK)
    SET col2 = 1

上面的陈述在语法上可能是正确的,但是如果有人找到这样的例子,请给我一个链接。

但是:我的完整 SQL 如下所示。在执行期间我收到错误:

Conflicting locking hints are specified for table "table1". This may be caused by a conflicting hint specified for a view.

为什么我不能使用 WITH (NOLOCK) 进行选择并使用 WITH (ROWLOCK) 进行更新?

;WITH CTE AS 
( 
    SELECT TOP(5) table1.col2
    FROM table1 WITH (NOLOCK) INNER JOIN table2 WITH (NOLOCK) ON table1.id = table2.id 
    WHERE table1.col3 = 2
    ORDER BY table1.id    
) 
UPDATE CTE WITH (ROWLOCK)
SET col2 = 1

最佳答案

NOLOCK 不适用于引用要修改的表的查询部分。在 SQL Server 更新语句中,在测试每一行时都会对其进行短暂的 U 锁定。这是一种避免死锁的机制。它可以防止对每个 S 锁定一行进行多次更新以供读取,然后尝试对其进行 X 锁定。

据我所知,你无法让 U 型锁消失。但是您可以通过自连接将 U 锁定的行数减少到绝对最小值:

update t1
set ...
from T t1 with (rowlock)
where t1.ID in (select TOP 5 ID from T t2 with (nolock) where ... order by ...)

这会增加一点开销,但它允许您使用 NOLOCK 进行读取。

考虑对读取使用快照隔离。 NOLOCK 存在某些问题,例如查询随机中止。

关于sql - 更新+使用(行锁)+ CTE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27177451/

相关文章:

sql - 检查字段是否为数字,然后在一个语句中仅对这些字段执行比较?

mysql - Web 开发 - SQL 创建最近的页面

sql - SQL 中日期格式的问题

sql - 合并到不匹配时插入 if 条件

sql-server - 在 T-SQL 中创建新索引时需要重新索引吗?

sql-server-2005 - SQL 递归菜单排序

sql - 使用 SQLite 的完全外部连接

c# - 从 SQL Server 中使用 xp_cmdshell 调用 Outlook COM 库

sql - 查找内部包含重复字母的字符串

sql - 根据条件计算子表中记录数的最快方法