none
requête recursive et boucle infinie

    General discussion

  • Bonjour,
    J'ai un problème de requête recursive qui boucle sur elle-même.
    Je souhaite empêcher une requête récursive de boucler sur un élément si celui-ci a déjà été trouvé à un niveau inférieur.
    Voici un jeu de données de test :
    create table
    testloop
    (
      name VARCHAR(MAX),
      relatedto VARCHAR(MAX)
    )
    insert into testloop
    select 'olivier', 'francois'
    union select 'francois', 'henri'
    union select 'henri', 'olivier'

    Si j'execute la requête suivante, ça plante, le niveau maximum de récusrsivité étant atteint:

    with t as (
    select name, relatedto, 1 as level
    from
       
    testloop
    where name='olivier'
    union all
    select testloop.name, testloop.relatedto, T.level+1 as level
    from
       
    testloop inner join
       
    t on t.relatedto = testloop.name
    )
    select *
    from t

    Si j'essaye cette requête, ça plante également parce que je fait référence deux fois à ma CTE de récursion :

    with t as (
    select name, relatedto, 1 as level
    from
       
    testloop
    where name='olivier'
    union all
    select testloop.name, testloop.relatedto, T.level+1 as level
    from
       
    testloop inner join
       
    t on t.relatedto = testloop.name
    where testloop.name not in (select name from t T1 where t1.level < t.level)
    )
    select *
    from t

    Comment arriver à stopper une récursion lorsqu'un élément trouvé a déjà été retrouvé à un niveau de récursion inférieur ?


    Olivier MARTY
    • Changed type Ciprian Duduiala Monday, May 16, 2011 5:58 AM pas de réponse de l'utilisateur qui a lancé la question
    Monday, May 09, 2011 12:53 PM

All replies

  • Bonjour,

    Quel est le but ici ? L'utilisation d'une CTE récursive ne me semble pas justifié. Il vous manque la notion de hiérarchie.

    ++


    MCDBA | MCITP SQL Server 2005 / SQL Server 2008 | LPI Linux 1
    Tuesday, May 10, 2011 7:46 AM
    Moderator
  • Effet, dans cet exemple, l'utilisation d'une CTE ne serait pas justifié, il s'agit d'un jeu de test réduit qui produit une boucle. Mes données de productions sont nettement plus complexes et utilisent une table n-to-n pour faire la liaison entre divers éléments. Comme la requête est un peu lourde, je préfère travailler sur une table simple et un jeu de test réduit qui reproduit mon problème.

     


    Olivier MARTY
    Wednesday, May 11, 2011 9:58 AM
  • Postez la DDL de vos tables (le strict minimum avec les colonnes qui nous intéressent).

    ++


    MCDBA | MCITP SQL Server 2005 / SQL Server 2008 | LPI Linux 1
    Thursday, May 12, 2011 8:04 AM
    Moderator
  • Bonjour, Warny,

    Pouvez-vous nous donner les infos demandées par Mikedavem ? Sinon, il sera difficile à vous aider. Ensuite, pouvez-vous nous dire si dans le cas de vos données réelles vous avez aussi besoin d’un champ additionnel level pour la hiérarchie comme dans l’exemple réduit ? Je vous demande parce qu’en cette situation je ne vois pas comment une CTE pourrait résoudre votre problème.

    Cordialement,

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    Friday, May 13, 2011 11:03 AM
  • Voici le script de création de la table.

    CREATE TABLE [dbo].[ott_Bills](
     [idBill] [int] IDENTITY(1,1) NOT NULL,
     (...)
     CONSTRAINT [PK_OTT_BILLS] PRIMARY KEY CLUSTERED
    (
     [idBill] ASC
    )
    )

    GO

    CREATE TABLE [dbo].[ott_BillsComplementary](
     [idBill] [int] NOT NULL,
     [idBillComplementary] [int] NOT NULL,
    PRIMARY KEY CLUSTERED
    (
     [idBill] ASC,
     [idBillComplementary] ASC
    )
    )

    GO

    Dans la table ott_BillsComplementary idBill et idBillComplementary sont des clefs étrangère sur ott_Bills.idBill


    Olivier MARTY
    Monday, May 16, 2011 1:02 PM