Подтвердить что ты не робот

Ошибка CTE: "Типы не совпадают между якорем и рекурсивной частью"

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

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

Где я делаю ошибку?

4b9b3361

Ответ 1

То, что он говорит:

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

Ответ 2

Вам нужно отобразить оба поля 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

Ответ 3

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

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

;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

;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

Ответ 5

В моем случае я испортил последовательность столбцов в верхнем и нижнем предложениях UNION ALL. И оказалось, что столбец varchar появился "под" int. Легкая ошибка сделать из вас много столбцов

Ответ 6

Я бы порекомендовал использовать 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

Ответ 7

;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