关键字'with'附近的语法不正确...前一个语句必须以分号结尾

40

我正在使用 SQL Server 2005。我的存储过程中有2个 WITH 子句。

WITH SomeClause1 AS
(
  SELECT ....
)
WITH SomeClause2 AS
(
  SELECT ....
)

但是出现了错误

关键字“with”附近的语法不正确。如果此语句是公共表达式或xmlnamespaces子句,则必须使用分号终止前一语句。

我的选项是什么?有我不知道的任何分隔符吗?

4个回答

75

使用逗号来分隔CTE。

;WITH SomeClause1 AS
(
  SELECT ....
)
, SomeClause2 AS
(
  SELECT ....
)

同样适用于SQL Server 2008的MERGE语句,它必须以分号结尾! - marc_s
gbn,你救了我的命。我在 Delphi 的查询组件中遇到了这个错误,束手无策!再次感谢你和 Duncan。 - Hein du Plessis

18

不要像错误提示所说的那样在前一个语句中添加";"。只需要养成总是像这样编码:";WITH",你就没问题了...

;WITH SomeClause1 AS
(
  SELECT ....
)

然而,您必须使用逗号连接多个公用表达式(CTE),但是在“;WITH”之前始终有一个分号:

;WITH SomeClause1 AS
(
  SELECT ....
)
,SomeClause2 AS
(
  SELECT ....
)

2

我将兼容性级别更改为较新的版本(2017 - 140)。这对我起了作用。 - Gil Allen

1

对我不起作用。

在我的情况下,我正在使用CTE值在表值用户定义函数的RETURN子句中。如果我将RETURN子句包装在BEGIN-END中,我会收到相同的错误消息,但裸的RETURN()子句可以正常工作。我认为这种情况下错误消息是不正确的。

这个有效:

CREATE FUNCTION [dbo].[ft_SplitStringOnChar]
      (
      @s varchar(8000),
      @sep char(1)
      )

RETURNS TABLE
AS

RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn AS TokenNumber,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS TokenString
    FROM Pieces
  )

GO  

This does not:

CREATE FUNCTION [dbo].[ft_SplitStringOnChar]
      (
      @s varchar(8000),
      @sep char(1)
      )

RETURNS TABLE
AS
BEGIN
;
RETURN (
    WITH Pieces(pn, start, stop) AS (
      SELECT 1, 1, CHARINDEX(@sep, @s)
      UNION ALL
      SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
      FROM Pieces
      WHERE stop > 0
    )
    SELECT pn AS TokenNumber,
      SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS TokenString
    FROM Pieces
  )
END
GO  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接