Ошибка 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".
Где я делаю ошибку?
Ответы
Ответ 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