Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server
MS SQL-Server Forum Microsoft SQL-Server. Avant de poster -> FAQ SQL-Server, Tutoriels SQL-Server
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/11/2011, 17h44   #1
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
Par défaut Problème requête récursive

Bonjour,
j'ai un soucis de requête récursive.
Voici ce que je cherche à faire :
Récupérer tous les accessoires, sous-accessoires ... des produits

Voici mes tables :
Produit (IdProduit, IdGroupeAccessoire)
GroupeAccessoire (IdGroupeAccessoire)
ProduitGroupeAccessoire(IdProduitGroupeAccessoire, IdProduit, IdGroupeAccessoire)

En gros un produit à un groupe d'accessoires qui sont également des produits, et ces produits peuvent également avoir des groupes d'accessoires et ainsi de suite ...

Voici mon message d'erreur :
Citation:
Msg*530, Niveau*16, État*1, Ligne*1
L'instruction a été terminée. La récursivité maximale 100 a été épuisée avant la fin de l'instruction.
Voici mon code :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
WITH 
   tree (IdProduitPrincipal, IdGroupeAccessoire, IdProduitAcc)
	AS (
		SELECT p.IdProduit AS IdProduitPrincipal, p.IdGroupeAccessoire, pga.IdProduit AS IdProduitAcc
		FROM Produit p
		JOIN GroupeAccessoire ga ON ga.IdGroupeAccessoire = p.IdGroupeAccessoire
		JOIN ProduitGroupeAccessoire pga ON pga.IdGroupeAccessoire = ga.IdGroupeAccessoire
		--where p.IdProduit = 865
 
		UNION ALL
 
		SELECT p.IdProduit, p.IdGroupeAccessoire, pga.IdProduit AS IdProduitAcc
		FROM produit p
		JOIN GroupeAccessoire ga ON ga.IdGroupeAccessoire = p.IdGroupeAccessoire
		JOIN ProduitGroupeAccessoire pga ON pga.IdGroupeAccessoire = ga.IdGroupeAccessoire
		JOIN tree t ON t.IdProduitAcc = p.IdProduit 
	)
 
	SELECT * FROM tree
	ORDER BY IdProduitPrincipal
	--OPTION (MAXRECURSION 100)
;
Par contre si j'enlève le commentaire (where p.IdProduit = 865) pour un IdProduit donné, cette requête fonctionne.

Que dois je faire, je ne comprends pas l'erreur !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/11/2011, 18h29   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Décommentez aussi l'instruction OPTION (MAXRECURSION) et mettez plus que 100 :
Code :
OPTION (MAXRECURSION 10000)
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2011, 07h20   #3
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
n'avez vous pas une référence circulaire dans vos données?
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2011, 08h53   #4
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
Bonjour,

Même avec OPTION (MAXRECURSION ) (sans limite) ma requête n'aboutit pas !

Qu'appelez vous référence circulaire ?
Dans ma table de Produit j'ai bien une référence ProduitSubstitution qui pointe vers un Produit, donc effectivement j'ai bien une liaison qui boucle sur ma table mais je n'appelle pas cette propriété dans ma requête !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2011, 09h34   #5
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Architecte de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Certes mais vous extrayez un idproduit de ProduitGroupeAccessoire puis vous faites votre récursion dessus... (join sur tree dans le union all)

A mon humble avis cela crée une récursion sans fin du fait d'une référence circulaire (un idproduitAcc prends la valeur d'un idproduitPrincipal déjà traité cela ne devrait jamais arriver...)

Amusez vous à tester la récursion un par un en insérant dans une table par exemple vous trouverez la données incriminée...
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2011, 10h02   #6
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
Ok c'est surement le cas ...

Mais comment je teste ça ?
J'ai 8000 Produit ?! je ne peux pas faire ça un par un !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2011, 10h11   #7
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Ben tu procèdes par dichotomie :

http://fr.wikipedia.org/wiki/Dichotomie

En gros :

Tu prends les 4000 premiers produits.
=> Si ça plante, tu prends les 2000 premiers.
=> Si ça plante pas, tu prends les 2000 à 3000.
=> Si ça plante, tu prends les 2000 à 2500
Etc.

Jusqu'à ce que tu trouves ton produits qui merde

En gros, tu reprends le jeu de Pierre et de Paul : quand ça plante, c'est que ton produit bloquant est dans l'interval testé, donc que Paul à dit "oui"

PS : A noter qu'il n'est pas exclu que tu aies plusieurs références circulaires, si c'est le cas, il faudra reprendre à 0 tant qu'il restera des produits bancals... Sacré farceur de Paul
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/11/2011, 10h27   #8
Candidat au titre de Membre du Club
 
Inscription : février 2011
Messages : 70
Détails du profil
Informations forums :
Inscription : février 2011
Messages : 70
Points : 13
Points : 13
Ok mais où est Jacques ...

Au final j'ai trouvé la solution !
En cherchant un peu dans votre direction, j'avais bien un problème de données circulaire, car je faisais le test sur tous les produits !
En ajoutant des clauses, j'ai mieux ciblé ma récursivité et du coup ça marche !

Merci pour vos réponses qui ont permis de m'orienter vers la lumière !
weebo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 14h29.


 
 
 
 
Partenaires

Hébergement Web