我们一直在兼容模式下运行SQL Server 2005数据库,向下移动到兼容级别80(SQL Server 2000)。
我们确实需要开始使用表UDF,并且有一个特定的存储过程是动态的,我们需要使用varchar(MAX)
。所以我们正在测试关闭兼容模式并在本机2005模式下运行数据库。
当我在测试副本上执行此操作时,运行在80级运行正常的存储过程时出现错误。错误与WITH
语句有关。我在存储过程中有一个CTE,但正在执行的代码分支甚至没有触及它并将其包含在正在执行的SQL中。我在WITH
之前加了一个分号。问题似乎可能是我的WITH (NOLOCK)
陈述?但他们不是CTE。
错误
关键字'with'附近的语法不正确。如果此语句是公用表表达式或xmlnamespaces子句,则必须以分号结束前一个语句。
答案 0 :(得分:0)
我知道发生了什么事。如果您正在使用CTE&WITH和(NOLOCK),如果您首先使用WITH(NOLOCK),则需要终止CTE的WITH语句。
这很好......
WITH cteAreaCOdes(AreaCode, State)
AS
(
SELECT AreaCode, State from tblAreaCodes
)
SELECT * FROM tblCustomers WITH(NOLOCK)
SELECT * FROM cteAreaCOdes WITH(NOLOCK)
这不......
SELECT * FROM tblCustomers WITH(NOLOCK)
WITH cteAreaCOdes(AreaCode, State)
AS
(
SELECT AreaCode, State from tblAreaCodes
)
SELECT * FROM cteAreaCOdes WITH(NOLOCK)
引发错误......
Msg 319,Level 15,State 1,Line 6 关键字'与'附近的语法不正确。如果此语句是公用表表达式或xmlnamespaces子句,则必须以分号结束前一个语句。
然后我从tblCustomers中移除了WITH并使用了(NOLOCK),因为在2k5中不需要WITH,但这也没有用。
引发错误......
Msg 336,Level 15,State 1,Line 6 “cteAreaCOdes'附近的语法不正确”。如果这是一个公用表表达式,则需要使用分号显式终止前一个语句。
完全删除(NOLOCK)并且只运行一个简单的SELECT语句会引发相同的错误。所以基本上如果我使用CTE,我需要在它之前有任何其他SELECT语句时终止它。
这实际上不应该如此令人困惑,终止所有WITH语句的简单经验法则会修复我的所有问题,问题出现了,因为兼容模式80(SQL 2k)中的SQL2k5允许所有这些语句我上面试过工作得很好。
因此它允许CTE(SQL 2k没有),但是,它不需要在任何地方终止WITH语句。