Ошибка CTE: «Типы не совпадают между якорем и рекурсивной частью» - PullRequest
53 голосов
/ 03 декабря 2009

Я выполняю следующее заявление:

;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".

Где я совершаю ошибку?

Ответы [ 5 ]

90 голосов
/ 03 декабря 2009

Именно то, что написано:

'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)), если снова произойдет сбой

22 голосов
/ 03 декабря 2009

Вам нужно привести оба поля нм

;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
5 голосов
/ 22 марта 2018

Для меня проблема была в другом сопоставлении.

Только это мне помогло:

;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 голосов
/ 03 декабря 2009
;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
0 голосов
/ 03 февраля 2015
;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
...