74 votes

Erreur de CTE : "Les types ne correspondent pas entre l'ancre et la partie récursive"

J'exécute la déclaration suivante :

;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

...qui se termine par l'erreur...

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

Où est-ce que je fais l'erreur ?

121voto

gbn Points 197263

Exactement ce qu'il dit :

'name1' a un type de données différent de celui de 'name' + CAST((rn+1) as varchar(255))

Essayez ceci (non testé)

;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

En principe, vous devez veiller à ce que la longueur corresponde également. Pour la partie récursive, vous devrez peut-être utiliser la fonction CAST('name' AS varchar(4)) s'il échoue à nouveau

0 votes

Monsieur, c'est ce que je viens de faire. CAST(1 as varchar(255))

7 votes

Une fois de plus, Stackoverflow a répondu à ma question avant que je ne la pose. Merci @priyanka & @gbn

7 votes

Au cas où vous obtiendriez toujours cette erreur, vous devez également vous assurer que la collation de votre base de données et la collation de votre table sont identiques. En d'autres termes, les collations doivent être les mêmes dans les requêtes récursives CTE.

29voto

astander Points 83138

Vous devez lancer les deux champs 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

0 votes

C'est ce que je viens de faire. CAST(1 as varchar(255)) . Une erreur stupide a oublié de faire le cast.( :

1 votes

Après m'être battu avec sql, j'ai fini par convertir les deux en décimales et cela a réglé mon problème. merci !

12voto

Vitaly Borisov Points 1042

Pour moi, le problème venait d'une collation différente.

Il n'y a que ça qui m'a aidé :

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

J'espère que cela pourra aider quelqu'un d'autre.

4voto

priyanka.sarkar Points 5980
;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

7 votes

Votre réponse est comme les autres, vous pourriez modifier l'une d'entre elles et supprimer celle-ci. Les futurs lecteurs comme moi vous remercieront pour cette clarté ;)

1voto

BusinessAlchemist Points 405

Dans mon cas, je me suis trompé dans l'ordre des colonnes dans les clauses supérieures et inférieures de l'article. UNION ALL . Et il s'est avéré qu'un varchar est apparue "sous" une int un. Une erreur facile à commettre si vous avez beaucoup de colonnes.

0 votes

Merci beaucoup ! !! c'est la solution qui a fonctionné pour moi. un oubli très facile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X