2011-01-24 115 views
7

當怪怪的我有一個串接查詢: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'    when using `NVARCHAR(MAX)` and 
'E//fixedurl/testing1234' when using `NVARCHAR(4000)`

我最好的猜測是使用NVARCHAR(MAX)會導致@path在每次設置時都會被重新輸入,因此在重新輸入之前丟失了內容集,或者在第一次設置時輸入了內容,然後後續的連接調用將自動失敗。

我很想真正理解這種行爲的根本原因。

UPDATE

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 [email protected] 
     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 
+0

'url_segment`類型是什麼? – 2011-01-24 10:02:29

+0

我以前使用這種方法進行連接時有類似的結果。 (它只以一行的值而不是全部結束)我從未注意到`datatype`已經起作用了。有時您需要稍微調整一下查詢以獲取所需的執行計劃。你可以發佈兩個計劃嗎? (或者你當然可以像使用XML PATH一樣在SQL Server 2005上進行文檔編寫工作)參見http://support.microsoft.com/kb/287515/en-us – 2011-01-24 10:11:08

回答

4

這種方法來字符串連接通常的工作,但它不能保證。

the KB article for a similar issue中的官方行是「聚合級聯查詢的正確行爲未定義」。

計劃之間必須有一些細微的差異。您可以調整查詢以刪除差異並獲得所需的執行計劃,或者您可以/當然應該像使用SQL Server 2005一樣使用XML PATH,並將其記錄爲可行。