我刚在工作站上设置SQL Server 2008 SP2 以运行本地版本的数据库。生产数据库是SQL Server 2008 R2 。一位同事正在他的工作站上运行SQL Server 2005。
我的数据库使用以下代码抛出错误,而其他服务器上同一数据库的其他实例运行此查询时没有错误。
WITH Posts AS (
SELECT TOP 10 *
FROM TBL_MSG_LATEST (NOLOCK)
WHERE TBL_MSG_LATEST.STATUS = 1
)
SELECT * FROM Posts (NOLOCK)
...抛出此错误:
Msg 215,Level 16,State 1,Line 6 为对象'Posts'提供的参数不是函数。如果参数用作表提示,则需要WITH关键字。
在(NOLOCK)
之后移除Posts
会让我的数据库感到满意。
我不熟悉SQL Server,所以我并不完全了解CTE,但我相信这里NOLOCK
甚至可能不需要。
但是,我们不满意为了满足我的开发环境而对代码库进行更改。
我的新数据库环境是否存在配置差异?是否有正当理由删除我无法从错误消息中解密的NOLOCK
?
答案 0 :(得分:4)
从此页面:http://msdn.microsoft.com/en-us/library/ms187373.aspx
省略WITH关键字是一项不推荐使用的功能,将被删除 在Microsoft SQL Server的未来版本中。
所以这会奏效。
WITH Posts AS (
SELECT TOP 10 *
FROM TBL_MSG_LATEST WITH (NOLOCK)
WHERE TBL_MSG_LATEST.STATUS = 1
)
SELECT * FROM Posts WITH (NOLOCK)
不知道这是不是一个好主意,或者是否有任何影响。
答案 1 :(得分:1)
这似乎是CTE语法特有的。添加“WITH”不会改变NOLOCK的工作方式;它只是允许它起作用。
在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);
但这失败了:
WITH Posts AS (
SELECT ... FROM TBL_MSG_LATEST (NOLOCK)
)
SELECT * FROM Posts (NOLOCK);
这些都在CTE之外工作:
SELECT ... FROM TBL_MSG_LATEST NOLOCK;
SELECT ... FROM TBL_MSG_LATEST (NOLOCK);
SELECT ... FROM TBL_MSG_LATEST WITH (NOLOCK);
正确的语法是“WITH(NOLOCK)”。
但是 ...如果你把NOLOCK放在CTE中,你为什么还把它放在SELECT上?
请注意,Denali CTP3中的结果完全相同。