CTE错误:“锚点和递归部分之间的类型不匹配”

时间:2009-12-03 07:35:32

标签: sql sql-server tsql common-table-expression

我正在执行以下声明:

;WITH cte AS (
  SELECT 
    1 as rn, 
    'name1' as nm
  UNION ALL
  SELECT 
    rn + 1,
    nm = 'name' + CAST((rn + 1) as varchar(255))
  FROM cte a WHERE rn < 10)
SELECT * 
FROM cte

...完成错误......

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

我在哪里犯了错误?

8 个答案:

答案 0 :(得分:89)

究竟是什么意思:

'name1''name' + CAST((rn+1) as varchar(255))

的数据类型不同

试试这个(未经测试的)

;with cte as
(
select 1 as rn, CAST('name1' as varchar(259)) as nm
union all
select rn+1,nm = 'name' + CAST((rn+1) as varchar(255))
from cte a where rn<10)
select * from cte

基本上,你必须确保长度匹配。对于递归位,如果再次失败,则可能必须使用CAST('name' AS varchar(4))

答案 1 :(得分:22)

您需要投射两个nm字段

;with cte as
(
select  1 as rn, 
        CAST('name1' AS VARCHAR(255)) as nm
union all
select  rn+1,
        nm = CAST('name' + CAST((rn+1) as varchar(255)) AS VARCHAR(255))
from cte a where rn<10)
select * from cte

答案 2 :(得分:4)

;with cte as
(
select 1 as rn, 'name' + CAST(1 as varchar(255)) as nm
union all
select rn+1,nm = 'name' + CAST((rn+1) as varchar(255))
from cte a where rn<10)
select * from cte

答案 3 :(得分:4)

对我来说,问题在于不同的整理。

只有这对我有所帮助:

;WITH cte AS (
  SELECT 
    1 AS rn, 
    CAST('name1' AS NVARCHAR(4000)) COLLATE DATABASE_DEFAULT AS nm
  UNION ALL
  SELECT 
    rn + 1,
    nm = CAST('name' + CAST((rn + 1) AS NVARCHAR(255)) AS NVARCHAR(4000)) COLLATE DATABASE_DEFAULT
  FROM cte a WHERE rn < 10)
SELECT * 
FROM cte;

希望它可以帮助别人。

答案 4 :(得分:0)

就我而言,我弄乱了UNION ALL的top和bottom子句中的列顺序。结果发现varchar列出现在int列的下方。一个容易犯的错误,就是您有很多列

答案 5 :(得分:0)

我建议使用nvarchar(max)

WITH CTE AS (
SELECT x,x_name FROM (VALUES (1,CAST('' AS nvarchar(MAX)))) AS     test(x,x_name)
UNION ALL
SELECT x + 1 x, CONCAT(x_name,x+1)  FROM CTE WHERE x < 10 )
SELECT * FROM CTE

答案 6 :(得分:0)

如果在rcte的递归术语中使用CONCAT,则由于concat的输出类型为varchar(MAX),因此只需要在初始查询中强制转换列:

WITH rcte AS (
    SELECT 1 AS nr, CAST('1' AS varchar(MAX)) AS trail
    UNION ALL
    SELECT nr+1, CONCAT(trail, '/', nr+1)
    FROM rcte
    WHERE nr < 5
)
SELECT * FROM rcte;

enter image description here

答案 7 :(得分:-3)

;with tmp1(NewsId,DataItem ,HeaderText)
 as
  (

    select NewsId, LEFT(HeaderText, CHARINDEX(',',HeaderText+',')-1),
    STUFF(HeaderText, 1, CHARINDEX(',',HeaderText+','), '') 
    from Currentnews

    union all

    select NewsId, LEFT(HeaderText, CHARINDEX(',',HeaderText+',')-1),
    STUFF(HeaderText, 1, CHARINDEX(',',HeaderText+','), '')
    from tmp1
    where HeaderText > ''

   )

   select NewsId, DataItem
   from tmp1
   order by NewsId