简体   繁体   English

SQL Server 2008 SP2 中 CTE 上的 NOLOCK 错误

[英]Error from NOLOCK on CTE in SQL Server 2008 SP2

I've just set up SQL Server 2008 SP2 on my workstation to run a local version of a database.我刚刚在我的工作站上设置了 SQL Server 2008 SP2来运行本地版本的数据库。 The production database is SQL Server 2008 R2 .生产数据库是 SQL Server 2008 R2 A colleague is running SQL Server 2005 on his workstation.一位同事正在他的工作站上运行 SQL Server 2005。

My DB is throwing an error with the following code, while other instances of the same DB on the other servers run this query with no error.我的数据库使用以下代码引发错误,而其他服务器上同一数据库的其他实例运行此查询而没有错误。

WITH Posts AS (
    SELECT TOP 10 *
    FROM TBL_MSG_LATEST (NOLOCK)
    WHERE TBL_MSG_LATEST.STATUS = 1
) 
SELECT * FROM Posts (NOLOCK)

...throws this error: ...引发此错误:

Msg 215, Level 16, State 1, Line 6 Parameters supplied for object 'Posts' which is not a function.消息 215,级别 16,State 1,第 6 行为 object“帖子”提供的参数不是 function。 If the parameters are intended as a table hint, a WITH keyword is required.如果将参数用作表提示,则需要 WITH 关键字。

Removing the (NOLOCK) after Posts makes my DB happy.Posts之后删除(NOLOCK)让我的数据库很开心。

I'm not familiar with SQL Server, so I don't totally understand CTEs but I believe that this NOLOCK might not even be necessary here.我不熟悉 SQL 服务器,所以我不完全了解 CTE,但我相信这里甚至可能不需要这个NOLOCK

However, we aren't happy about making a change to the codebase just to satisfy my dev environment.但是,我们并不乐意仅仅为了满足我的开发环境而对代码库进行更改。

Is there a config difference with my newer DB environment?我的新数据库环境有配置差异吗? Is there a valid reason to remove the NOLOCK that I can't decipher from the error message?是否有正当理由删除我无法从错误消息中破译的NOLOCK

From this page: http://msdn.microsoft.com/en-us/library/ms187373.aspx从这个页面: http://msdn.microsoft.com/en-us/library/ms187373.aspx

Omitting the WITH keyword is a deprecated feature and will be removed in a future version of Microsoft SQL Server.省略 WITH 关键字是一项已弃用的功能,将在 Microsoft SQL 服务器的未来版本中删除。

So this will work.所以这会起作用。

WITH Posts AS (
    SELECT TOP 10 *
    FROM TBL_MSG_LATEST WITH (NOLOCK)
    WHERE TBL_MSG_LATEST.STATUS = 1
) 
SELECT * FROM Posts WITH (NOLOCK)

Don't know if it is a good idea or not or if it has any effect.不知道这是不是一个好主意或是否有任何效果。

This appears to be specific to CTE syntax.这似乎特定于 CTE 语法。 Adding the "WITH" won't change how the NOLOCK works;添加“WITH”不会改变 NOLOCK 的工作方式; it will just allow it to work.它只会让它工作。

With NOLOCK hints in CTEs, these both work:使用 CTE 中的 NOLOCK 提示,这些都有效:

WITH Posts AS (
    SELECT ... FROM TBL_MSG_LATEST NOLOCK
)
SELECT * FROM Posts NOLOCK;

WITH Posts AS (
    SELECT ... FROM TBL_MSG_LATEST WITH (NOLOCK)
)
SELECT * FROM Posts WITH (NOLOCK);

but this fails:但这失败了:

WITH Posts AS (
    SELECT ... FROM TBL_MSG_LATEST (NOLOCK)
)
SELECT * FROM Posts (NOLOCK);

These all work outside of a CTE:这些都在 CTE 之外工作:

SELECT ... FROM TBL_MSG_LATEST NOLOCK;
SELECT ... FROM TBL_MSG_LATEST (NOLOCK);
SELECT ... FROM TBL_MSG_LATEST WITH (NOLOCK);

The correct syntax is "WITH (NOLOCK)".正确的语法是“WITH (NOLOCK)”。

But ... if you're putting NOLOCK inside the CTE, why are you also putting it on the SELECT?但是……如果你把 NOLOCK 放在 CTE 里面,你为什么还要把它放在 SELECT 上呢?

Note that the results are all the same in Denali CTP3.请注意,Denali CTP3 中的结果都相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM