我对 BOL 短语感到困惑:
“不能为插入、更新或删除操作修改的表指定 READUNCOMMITTED 和 NOLOCK。SQL Server 查询优化器忽略 FROM 子句中适用于 UPDATE 或 DELETE 语句的目标表的 READUNCOMMITTED 和 NOLOCK 提示”[1]
例如,如果我写
--script 1)
UPDATE Test SET Txt=(Select Txt from TEST WITH(NOLOCK) where ID=1)
WHERE ID=1
它运行时没有错误(或警告),可能相当于
--script 2)
set transaction isolation level SERIALIZABLE;
begin tran
Declare @nvarm nvarchar(max);
Select @nvarm=Txt from Test where ID=1;
--Select @nvarm;
UPDATE Test SET Txt=@nvarm WHERE ID=1;
commit;
它也可以在没有错误或警告的情况下运行。
是否等效?
该表是相同的,但在 FROM 中,它在逻辑上是源表而不是目标表,我可以重写 1)与另一个(物理)表不同的源表:
--script 3)
select *
into testDup
from TEST;
GO;
UPDATE Test SET Txt=(SELECT Txt FROM TestDUP WITH(NOLOCK) where ID=1)
WHERE ID=1
为什么要在另一个表上忽略 NOLOCK?
或者,如果它是错误的,那么
如何编写具有“适用于 UPDATE 或 DELETE 语句的目标表的 FROM 子句中的 NOLOCK 提示”的 UPDATE 问题,因为即使在 1)和 2)中,物理表是相同的但在逻辑上源(在 SELECT 中)表和目标(在 UPDATE 中)表是不同的。
如何编写一个 UPDATE 语句来证明 WITH(NOLOCK) 被忽略?
为什么要完全忽略它?它被忽略了吗?
或者,如果这是一个错误的问题,那么
为什么语法允许保证被忽略的提示?
再一次,要么不可能(或者是吗?)写出像文档中那样写的声明,或者我不理解“忽略”的含义(忽略它是什么意思?或根本没有它?) ...
UPDATE2:
答案表明 NOLOCK 在 UPDATE 语句的 FROM 子句中未被(更新)忽略,BOL 文档 [1] 断言。
好吧,这个问题的本质:
你能给我任何例子(上下文),在 UPDATE 语句的 FROM 子句中忽略 NOLOCK 是有意义的吗?
[ 1 ]
表提示 (Transact-SQL)
SQL Server 2008 R2
http://msdn.microsoft.com/en-us/library/ms187373.aspx