10

特定の再帰CTEを実行しようとすると、次のエラーが発生します。

Msg 240, Level 16, State 1, Line 8
Types don't match between the anchor and the recursive part in column "data_list" of recursive query "CTE".

これはナンセンスです。各フィールドは明示的ににキャストされVARCHAR(MAX)ます。私を助けてください。私はこの問題に対する多くの回答をここや他の場所で読みましたが、そのすべてが問題の列を明示的にキャストすることをアドバイスしています。私はすでにこれを行っていますが、それでもエラーが発生します。

このコードはエラーを再現します:

if object_id('tempdb..#tOwner') IS NOT NULL drop table #tOwner;
CREATE TABLE #tOwner(id int identity(1,1), email varchar(max) );
insert into #towner values ( cast('123@123.321'  as varchar(max)));
insert into #towner values ( cast('tsql rage'    as varchar(max)));
insert into #towner values ( cast('another@e.c'  as varchar(max)));
insert into #towner values ( cast('einstein.x.m' as varchar(max)));

;WITH data AS (
    SELECT DISTINCT convert(varchar(max), email) datapoint FROM #tOwner 
), CTE ( data_list, datapoint, length ) AS ( 
        SELECT convert(VARCHAR(max),            ''           ),convert(VARCHAR(max),    ''     ),       0
    UNION ALL
        SELECT convert(VARCHAR(max),d.datapoint+';'+data_list),convert(VARCHAR(max),d.datapoint), length + 1
        FROM CTE c CROSS JOIN data d WHERE d.datapoint > c.datapoint 
)
SELECT D.data_list
FROM ( 
    SELECT data_list, RANK() OVER ( PARTITION BY 1 ORDER BY length DESC ) 
    FROM CTE 
) D ( data_list, rank )
WHERE rank = 1 ;

drop table #tOwner;

関連性があると思われる場合は、次をSELECT left(@@VERSION, 70)返します。

Microsoft SQL Server 2005 - 9.00.4053.00 (X64)   May 26 2009 14:13:01 
4

1 に答える 1

11

私の元の投稿に対するWill Aのコメントは、キーである照合を見つけました。投稿されたクエリは、マスター データベースでも機能しました。

照合順序を調べると、正しい方向に進んでいることがわかりました。

SELECT DATABASEPROPERTYEX('crm_mscrm', 'Collation') crmSQLCollation
crmSQLCollation
--------------------
Latin1_General_CI_AI
(1 row(s) affected)

SELECT DATABASEPROPERTYEX('master', 'Collation') masterSQLCollation
masterSQLCollation
----------------------------
SQL_Latin1_General_CP1_CI_AS
(1 row(s) affected)

後で熱狂的に検索したところ、この巨大なコードがありました。

  1. 各列の照合を明示的に指定し、
  2. 正常に実行され、
  3. 期待される結果を返します

ウィット:

if object_id('tempdb..#tOwner') IS NOT NULL drop table #tOwner;
CREATE TABLE #tOwner(id int identity(1,1), email nvarchar(max) );
insert into #towner values ( cast('123@123.321'  as nvarchar(max)));
insert into #towner values ( cast('tsql rage'    as nvarchar(max)));
insert into #towner values ( cast('another@e.c'  as nvarchar(max)));
insert into #towner values ( cast('einstein.x.m' as nvarchar(max)));

;WITH data AS (
    SELECT DISTINCT convert(nvarchar(max), email) datapoint FROM #tOwner 
), CTE ( data_list, datapoint, length ) AS ( 
        SELECT convert(nvarchar(max),            ''           ) Collate SQL_Latin1_General_CP1_CI_AS,convert(nvarchar(max),    ''     ) Collate SQL_Latin1_General_CP1_CI_AS,       0
    UNION ALL
        SELECT convert(nvarchar(max),d.datapoint+';'+data_list) Collate SQL_Latin1_General_CP1_CI_AS,convert(nvarchar(max),d.datapoint) Collate SQL_Latin1_General_CP1_CI_AS, length + 1
        FROM CTE c CROSS JOIN data d WHERE d.datapoint > c.datapoint 
)
SELECT D.data_list
FROM ( 
    SELECT data_list, RANK() OVER ( PARTITION BY 1 ORDER BY length DESC ) 
    FROM CTE 
) D ( data_list, rank )
WHERE rank = 1 ;

if object_id('tempdb..#tOwner') IS NOT NULL drop table #tOwner;

私の結果ウィンドウに美しく座っていることが期待されています:

data_list
------------------------------------------------
tsql rage;einstein.x.m;another@e.c;123@123.321;
于 2010-08-06T22:59:44.183 に答える