VARCHAR(MAX) ведет себя странно при объединении строки

У меня есть объединяющий запрос:

DECLARE @path NVARCHAR(max) 
SELECT @path = ISNULL(@path + '/', '') + url_segment 
    FROM navigation_self_and_parents(2813) ORDER BY depth ASC
SELECT @path

navigation_self_and_parents(2813) возвращается

id    par_id  title        url_segment    sequence        depth
2813  2816    testing1234  testing1234    0               0   
2816  2809    U            /fixedurl      0               -1   
2809  NULL    E            E              0               -2   

Мой конкатенационный запрос возвращает

'testing1234' при использовании `NVARCHAR(MAX)` и
'E//fixedurl/testing1234' при использовании `NVARCHAR(4000)`

Я думаю, что использование NVARCHAR(MAX) заставляет @path повторно вводиться каждый раз, когда он установлен, и, таким образом, теряет содержимое, установленное до повторного набора, или набирается в первый раз, когда он установлен, а затем последующие конкатенационные вызовы молча завершаются неудачей.

Я хотел бы по-настоящему понять причину этого поведения, хотя.

ОБНОВИТЬ

navigation_self_and_parents:

USE [SomeDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[navigation_self_and_parents]
(   
    @id int
)
RETURNS TABLE 
AS
RETURN 
(
    WITH navigation_self_and_parents (id, parent_id, title, url_segment, sequence_number, depth)
    AS
    (
        SELECT id, parent_id, title, url_segment, sequence_number, 0 FROM navigation_node WHERE id=@id 
        UNION ALL

        SELECT n.id, n.parent_id, n.title, n.url_segment, n.sequence_number, depth - 1 From navigation_node as n
        INNER JOIN navigation_self_and_parents as rn
        ON n.id = rn.parent_id
    )
    SELECT * FROM navigation_self_and_parents
)

navigation_node DDL:

CREATE TABLE [dbo].[navigation_node](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [title] [nvarchar](128) NULL,
    [url_segment] [nvarchar](max) NULL,
    [hidden] [bit] NOT NULL,
    [page_id] [int] NULL,
    [parent_id] [int] NULL,
    [sequence_number] [int] NOT NULL,
    [createdOn] [datetime] NOT NULL,
    [updatedOn] [datetime] NULL,
    [navigation_type_id] [int] NULL,
    ...snap

1 ответ

Решение

Такой подход к конкатенации строк обычно работает, но он не гарантирован.

Официальная строка в статье базы знаний по похожей проблеме: "Правильное поведение для запроса совокупной конкатенации не определено".

Должна быть небольшая разница между планами. Вы можете настроить запрос, чтобы устранить разницу и получить требуемый план выполнения, или вы можете / должны, конечно, просто использовать XML PATH как вы находитесь на SQL Server 2005, и это задокументировано для работы.

Другие вопросы по тегам