Sql server SQL Server 2008:NOLOCK如何为CTE工作?

Sql server SQL Server 2008:NOLOCK如何为CTE工作?,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有CTE,里面都用NOLOCK。但是,在使用子CTE的父CTE中,从这些CTE中选择CTE不使用NOLOCK,假定它已经是NOLOCK。最终选择也不使用NOLOCK 诸如此类: with cte1 as (select * from tab1 (nolock)), cte2 as (select * from cte1) select * from cte2 还是我写 with cte1 as (select * from tab1 (nolock)), cte2 as (select *

我有CTE,里面都用NOLOCK。但是,在使用子CTE的父CTE中,从这些CTE中选择CTE不使用NOLOCK,假定它已经是NOLOCK。最终选择也不使用NOLOCK

诸如此类:

with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1)

select * from cte2
还是我写

with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1 (nolock))

select * from cte2 (nolock)

谢谢

您不需要外部的
nolock
来避免在
选项卡1上使用共享锁。您可以通过设置SQL事件探查器跟踪来轻松验证这一点,该跟踪捕获
类别中的各种事件,过滤SSMS连接的spid并尝试这两个版本


nolock
是一个非常危险的设置,但是您是否知道使用它的所有可能的缺点(脏读、两次读取数据或根本不读取)?

您不需要外部
nolock
来避免在
tab1
上使用共享锁。您可以通过设置SQL事件探查器跟踪来轻松验证这一点,该跟踪捕获
类别中的各种事件,过滤SSMS连接的spid并尝试这两个版本


nolock
是一个非常危险的设置,但是,您是否知道使用它的所有可能的缺点(脏读、两次读取数据或根本不读取)?

最里面的
nolock
就足够了,无需对外部选择重复它

您可以通过启动事务而不结束它来测试这一点:

begin transaction
; with YourCte ( ...

然后,您可以使用ManagementStudio查看锁。它们将一直存在,直到事务超时。

最里面的
nolock
就足够了,不需要为外部选择重复它

您可以通过启动事务而不结束它来测试这一点:

begin transaction
; with YourCte ( ...

然后,您可以使用ManagementStudio查看锁。它们将一直在那里,直到事务超时。

NOLOCK for cte的工作方式与处理其他所有事务的方式相同:它会导致。请改用快照,请参阅。

NOLOCK for CTE的工作方式与处理其他所有内容的方式相同:它会导致。改用快照,请参阅。

对“外部”查询的锁定也适用于任何内部查询。CTE只是一个类似于视图或内联表udf的宏:没有更多,也没有更少。所以你实际上有(忽略NOLOCK提示)

从,在“备注”下

所有锁定提示都会传播到查询计划访问的所有表和视图,包括视图中引用的表和视图

在这种情况下,您只需要一个。不管在哪里

重要的是你在哪里有连接。如果cte1是两个表的联接,则每个表都需要它,。或者在更高/外部级别指定一次

哦,我将和其他人一起加入:

对“外部”查询的锁定也适用于任何内部查询。CTE只是一个类似于视图或内联表udf的宏:没有更多,也没有更少。所以你实际上有(忽略NOLOCK提示)

从,在“备注”下

所有锁定提示都会传播到查询计划访问的所有表和视图,包括视图中引用的表和视图

在这种情况下,您只需要一个。不管在哪里

重要的是你在哪里有连接。如果cte1是两个表的联接,则每个表都需要它,。或者在更高/外部级别指定一次


哦,我会和其他人一起加入:

我根本不会使用
SELECT*
NOLOCK
。鉴于SQL 2005及更高版本支持CTE,有比NOLOCK更好的方法确保您正在读取已提交但历史数据。我不希望长时间运行的报表锁定表。。我的其他选项是什么?我根本不会使用
SELECT*
NOLOCK
。鉴于SQL 2005及更高版本支持CTE,有比NOLOCK更好的方法确保您正在读取已提交但历史数据。我不希望长时间运行的报表锁定表。。我的其他选择是什么?取决于隔离级别。共享锁通常在读取数据后立即释放。具体取决于隔离级别。共享锁通常在读取数据后立即释放。