2011-01-24 8 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が設定されるたびに再入力され、再タイピングする前に設定された内容が失われたり、最初に設定されたときに入力された後、

私は本当にこの動作の根本的な原因を理解したいです。

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:

navigation_self_and_parents

UPDATEは

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'の種類は何ですか? –

+0

私は前に連結するこのアプローチで同様の結果を得ました。 (それはすべてではなく1つの行からの値で終わる)私は 'datatype'が部分的に果たしたことに気付かなかった。場合によっては、必要な実行計画を取得するためにクエリを微調整する必要があります。両方の計画を掲示できますか? (もちろん、SQL Server 2005のようにXML PATHを使用しても問題はありません)http://support.microsoft.com/kb/287515/en-us –

+0

@El Ronnocoはさらに更新された質問を更新しました詳細。 –

答えて

4

文字列の連結にこのアプローチは、通常動作しますが、それは保証されません。

the KB article for a similar issueの公式の行は、「集約連結クエリの正しい動作は未定義です」ということです。

計画間に若干の微妙な違いがあるはずです。 SQL Server 2005のようにクエリを調整して差分を取り除き、必要な実行計画を取得するか、もちろんXML PATHを使用することができます。これは文書化されています。

+0

@Martin - 私はそれが失敗するのを見たことがありません。このリンクは、集約クエリで関数を使用することを意味します。しかし、それはここに当てはまりますか? – RichardTheKiwi

+0

@cyberkiwi - リンクのコードを見ましたか?集約は使用しません。 'SELECT @ Str1 = @ Str1 + C1 LTRIM(RTRIM(C1))によるT1オーダーからのメッセージ@ –

+0

@Martin - FYIそれはテキストを一つの変数に集約しています。 by orderは、LTRIM、RTRIMの機能を伴います。 – RichardTheKiwi

関連する問題