0
votes

CTE passe dans une boucle infinie?

J'ai une structure de table comme celle-ci

​​  Entrez la description de l'image ici

où je veux recurier jusqu'à ce que si (texte_id = new_text_id) . Donc supposons que je passe 1 comme text_id je veux en retour 5 comme text_id à l'aide de CTE.

J'ai essayé mais ça va Dans une boucle infinie, essayé maxrecursion toujours xxx

s'il vous plaît dites-moi ce que je fais mal.

Mon objectif est d'utiliser ce CTE dans une fonction de base de données et d'appeler cette fonction de Java.

et peut-on utiliser un CTE à l'intérieur d'une fonction. Si oui, comment?


2 commentaires

Si new_text_id pour la ligne 5 était null plutôt que 5, on dirait qu'il devrait fonctionner bien. Confusion entre ce que vous voulez que la condition de terminaison soit?


Je veux qu'il soit récursivement itérer jusqu'à text_id = new_text_id introuvable. Et inclure le dernier résultat I: E Si je passe 1 comme text_id, puis renvoyez tous les 5 résultats. Et si je passe 4 comme text_id, ne renvoyez que 2 derniers enregistrements.


3 Réponses :


0
votes

Qu'est-ce que vous avez commenté comme une condition de résiliation n'est pas cela. C'est une condition de jonction qui définit la relation entre l'itération actuelle et la suivante.

Je pense que vous voulez: xxx


0 commentaires

0
votes

Pouvez-vous essayer cette question ci-dessous. J'ai passé text_id = 1 xxx


1 commentaires

Il n'a pas fonctionné car il ne donne que la sortie où text_id = new_text_id. Mais j'ai besoin de toutes les données. Mais merci d'avoir essayé. La solution mentionnée ci-dessus par @IPTR a travaillé pour moi s'il vous plaît examiner cela.



1
votes
create table dbo.text_master_test
(
text_id int,
text_details nvarchar(max),
new_text_id int
)
go

insert into text_master_test
values(1, 'det 1',2), (2, 'det 2',3), (3, 'det 3',4), (4, 'det 4',5), (5, 'det 5',5);
go


WITH textHierarchy AS (
    SELECT tm.text_id, tm.new_text_id, nullif(tm.new_text_id, tm.text_id) as next_text_id
    FROM text_master_test tm 
    WHERE tm.text_id = 1
    UNION ALL
    SELECT tm.text_id, tm.new_text_id, nullif(tm.new_text_id, tm.text_id) as next_text_id
    FROM text_master_test as tm
    JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.next_text_id 

)
SELECT * FROM textHierarchy;
go


create function dbo.textrecursion(@start_text_id int)
returns table
as
return
(
WITH textHierarchy 
AS 
(
    SELECT tm.text_id, tm.text_details, tm.new_text_id, 
        nullif(tm.new_text_id, tm.text_id) as next_text_id
    FROM dbo.text_master_test tm 
    WHERE tm.text_id = @start_text_id
    UNION ALL
    SELECT tm.text_id, tm.text_details, tm.new_text_id,
        nullif(tm.new_text_id, tm.text_id) as next_text_id
    FROM dbo.text_master_test as tm
    JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.next_text_id 
)
select text_id, text_details, new_text_id
from textHierarchy
);
go

select *
from dbo.textrecursion(1)

select *
from dbo.textrecursion(4)

select *
from dbo.textrecursion(5)
go

drop function dbo.textrecursion;
go
drop table dbo.text_master_test
go

2 commentaires

Merci! Cela a fonctionné super. Une question pourquoi avez-vous utilisé nullif (tm.new_text_id, tm.text_id). Le CTE ne fonctionne pas sans elle


vous pouvez ignorer complètement la colonne NULLIF PARTIE & NEXT_TEXT_ID dans le CTE et utiliser le où txth.text_id <> txtth.new_text_id - Condition de terminaison dans la réponse par GMB .. Il y a une infime différence de la façon dont le CTE est exécuté mais pas si important.