«Неверный синтаксис рядом с ключевым словом WITH» в функции, возвращающей XML с выражением CTE - PullRequest
1 голос
/ 14 июля 2011

Я пытаюсь написать функцию для поддержки некоторого (устаревшего) кода SQL, функция будет использоваться как часть запроса:

SELECT
  q.*,
  fn_qncatxml(q.number, q.version) AS categories --XML aggregated category hierarchy
FROM
  [dbo].[qn] q

К сожалению, следующий подход не работает, поскольку в SQL Server есть некоторые известные проблемы с выражениями CTE в функции (точка с запятой перед решением WITH). К сожалению, я не уверен, как применить это решение к функции, возвращающей скаляр, например:

CREATE FUNCTION [dbo].[fn_qncatxml](@qnnumber INT, @qnversion INT)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN
  RETURN
  (
    WITH [categories] AS
    (
      SELECT [qn].[number], [qn].[version], [cat].[catnumber], [qncat].[itemnumber], [cat].[parent], [cat].[description], 0 AS [distance]
      FROM [qn]
      LEFT JOIN [qncat] ON [qncat].[qnnumber] = [qn].[number] AND [qncat].[qnversion] = [qn].[version]
      LEFT JOIN [cat] ON [cat].[catnumber] = [qncat].[catnumber] AND [cat].[status] = '1'
      WHERE [qn].[number] = @qnnumber AND [qn].[version] = @qnversion

      UNION ALL

      SELECT [categories].[number], [categories].[version], [cat].[catnumber], [categories].[itemnumber], [cat].[parent], [cat].[description], [categories].[distance] + 1 AS [distance]
      FROM [categories]
      JOIN [cat] ON [cat].[catnumber] = [categories].[parent]
      WHERE
        [cat].[status] = '1'
    )
    SELECT DISTINCT * FROM [categories] FOR XML PATH('')
  )
END

Когда я обрежу часть между WITH и FOR XML PATH (''), приведу несколько допустимых аргументов и выполню этот блок, он отлично работает.

Кто-нибудь знает, как заставить этот синтаксис функции CTE работать в моем сценарии?

1 Ответ

3 голосов
/ 14 июля 2011
CREATE FUNCTION [dbo].[fn_qncatxml](@qnnumber INT, @qnversion INT)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN
  DECLARE @Ret xml;

  WITH [categories] AS
  (
    SELECT [qn].[number], [qn].[version], [cat].[catnumber], [qncat].[itemnumber], [cat].[parent], [cat].[description], 0 AS [distance]
    FROM [qn]
    LEFT JOIN [qncat] ON [qncat].[qnnumber] = [qn].[number] AND [qncat].[qnversion] = [qn].[version]
    LEFT JOIN [cat] ON [cat].[catnumber] = [qncat].[catnumber] AND [cat].[status] = '1'
    WHERE [qn].[number] = @qnnumber AND [qn].[version] = @qnversion

    UNION ALL

    SELECT [categories].[number], [categories].[version], [cat].[catnumber], [categories].[itemnumber], [cat].[parent], [cat].[description], [categories].[distance] + 1 AS [distance]
    FROM [categories]
    JOIN [cat] ON [cat].[catnumber] = [categories].[parent]
    WHERE
      [cat].[status] = '1'
  )
  SELECT @Ret = (SELECT DISTINCT * FROM [categories] FOR XML PATH(''))

  RETURN @Ret
END
...