Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
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 13/05/2011, 12h38   #1
Membre actif
 
Inscription : mai 2004
Messages : 283
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 283
Points : 154
Points : 154
Envoyer un message via MSN à cosmos38240
Par défaut Cursor boucle infinie

Bonjour,

Je debute en SQL Serveur 2005 voici une boucle sur mon cursor qui tourne indefiniment :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
DECLARE backup_userpref_cursor CURSOR FOR 
    SELECT realTimeDisplayCategoryId, xmlDocument
    FROM displayPrefBackup a, displayPrefLayoutBackup b 
    WHERE a.displayPrefBackupId = b.displayPrefBackupId
	AND a.displayPrefBackupName = @Param_backupName;
 
PRINT '-------- V1 --------';
 
 
	SET @Output_ReturnCode = 0
	SET @Output_ReturnMessage = 'OverrideDisplayPrefFromBackup: OK'
 
	IF @Param_wellUid = ''
		SET @Param_wellUid = NULL
	IF @Param_userLogin = ''
		SET @Param_userLogin = NULL
	IF @Param_backupName = ''
		SET @Param_backupName = NULL
 
	IF @Param_wellUid IS NOT NULL AND @Param_userLogin IS NOT NULL AND @Param_backupName IS NOT NULL 
		--BEGIN TRY
		BEGIN
			SELECT @userId = userId
			FROM dbo.aspnet_users 
			WHERE userName = @Param_userLogin
PRINT '-------- V2 --------';
			OPEN backup_userpref_cursor;
			FETCH NEXT FROM backup_userpref_cursor 
			INTO @realTimeDisplayCategoryId, @layoutXml;
PRINT '-------- V3 --------';
			WHILE @@FETCH_STATUS = 0
			BEGIN
PRINT '-------- V4 --------';
				DECLARE welluserlayout_cursor CURSOR FOR 
				SELECT wellUserLayoutId
				FROM wellUserLayout
				WHERE realTimeDisplayCategoryId = @realTimeDisplayCategoryId
				AND wellUid = @Param_wellUid;	
				PRINT '-------- V5 --------' + Convert(varchar(500),@realTimeDisplayCategoryId) + @Param_wellUid;
				OPEN welluserlayout_cursor;
				FETCH NEXT FROM welluserlayout_cursor INTO @wellUserLayoutId;
 
				WHILE @@FETCH_STATUS = 0
PRINT '-------- V6 --------';
				BEGIN
PRINT '-------- V7 --------';
					UPDATE xmlLayoutProperty
					SET xmlDocument = @layoutXml 
					WHERE wellUserLayoutId = @wellUserLayoutId;
PRINT '-------- V8 --------';
				END
				CLOSE welluserlayout_cursor;
				DEALLOCATE welluserlayout_cursor;	
			END
			CLOSE backup_userpref_cursor;
			DEALLOCATE backup_userpref_cursor;	
		--END TRY
et voici le print :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-------- V1 --------
-------- V2 --------
-------- V3 --------
-------- V4 --------
-------- V5 --------2gWeb_well_G000001_000000007913
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
-------- V6 --------
Si quelqu'un pouvait m'aider sour Oracle je connais mais la suis perdu.

Merci
cosmos38240 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 13h13   #2
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Bonjour,

Citation:
Code :
AND wellUid = @Param_wellUid;
@Param_wellUid est NULL, donc le prédicat est faux ...

En outre les performances des curseurs, quel que soit le SGBDR (R que vous avez dû oublier ...) sont catastrophiques ...

SQL est un langage :

- ensembliste, donc il est conçu pour traiter les lignes dans leur ensemble, et non pas dans leur unité comme vous le faites
- déclaratif : vous décrivez le résultat que vous souhaitez obtenir, pas la façon dont vous voulez l'obtenir, comme dans un langage fonctionnel

Donc quand vous codez en SQL, oubliez les autres langages

Une requête comme celle qui suit fait parfaitement le boulot en très peu de temps :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
;WITH
	CTE AS
	(
		SELECT		realTimeDisplayCategoryId
				, xmlDocument
		FROM		displayPrefBackup AS a
		INNER JOIN	displayPrefLayoutBackup AS b 
					ON a.displayPrefBackupId = b.displayPrefBackupId
		WHERE		a.displayPrefBackupName = @Param_backupName
	)
UPDATE		xmlLayoutProperty
SET		xmlDocument = C.xmlDocument
FROM		xmlLayoutProperty AS XLP
INNER JOIN	CTE AS C
			ON XLP.realTimeDisplayCategoryId = C.realTimeDisplayCategoryId
INNER JOIN	wellUserLayout AS WUL
			ON WUL.wellUserLayoutId = C.realTimeDisplayCategoryId
WHERE		WUL.wellUid IS NULL
Et il doit même être possible d'écrire quelque chose comme :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
UPDATE		xmlLayoutProperty
SET		xmlDocument = C.xmlDocument
FROM		xmlLayoutProperty AS XLP
INNER JOIN	CTE AS C
			ON XLP.realTimeDisplayCategoryId = C.realTimeDisplayCategoryId
INNER JOIN	wellUserLayout AS WUL
			ON WUL.wellUserLayoutId = C.realTimeDisplayCategoryId
INNER JOIN	displayPrefBackup AS A 
			ON ???
INNER JOIN	displayPrefLayoutBackup AS B
			ON A.displayPrefBackupId = B.displayPrefBackupId
WHERE		WUL.wellUid IS NULL
AND		A.displayPrefBackupName = @Param_backupName
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/05/2011, 14h36   #3
Membre actif
 
Inscription : mai 2004
Messages : 283
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 283
Points : 154
Points : 154
Envoyer un message via MSN à cosmos38240
En effet ce n'est pas la meme approche.

Le champ realTimeDisplayCategoryId n'esiste pas dans la table xmlLayoutProperty mais je vais m'appuyer sur ton model pour essayer de faire en une requete

Merci
Michaël
cosmos38240 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 14h44   #4
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour,

Rien à redire à la réponse d'Elsuket

Sur la raison de votre boucle infini:

dans cette partie de code :
Code SQL :
1
2
3
4
5
6
7
8
9
10
 
WHILE @@FETCH_STATUS = 0
PRINT '-------- V6 --------';
				BEGIN
PRINT '-------- V7 --------';
					UPDATE xmlLayoutProperty
					SET xmlDocument = @layoutXml 
					WHERE wellUserLayoutId = @wellUserLayoutId;
PRINT '-------- V8 --------';
				END

Votre WHILE n'étant pas immédiatement suivi d'un BEGIN, c'est uniquement la ligne suivante qui est exécutée en boucle. Pour être plus clair, votre code est équivalent à
Code SQL :
1
2
3
4
5
6
7
8
9
10
11
 
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT '-------- V6 --------';
END
 
PRINT '-------- V7 --------';
					UPDATE xmlLayoutProperty
					SET xmlDocument = @layoutXml 
					WHERE wellUserLayoutId = @wellUserLayoutId;
PRINT '-------- V8 --------';

Cela dit, vous avez également un autre problème, car même si on retire vos lignes de print, (que vous avez, je suppose, ajoutées pour débugger), on obtient ceci :

Code SQL :
1
2
3
4
5
6
7
 
WHILE @@FETCH_STATUS = 0
BEGIN
	UPDATE xmlLayoutProperty
	SET xmlDocument = @layoutXml 
	WHERE wellUserLayoutId = @wellUserLayoutId;
END

Qui tournera en boucle (ou ne tournera pas du tout) car comme vous ne faites aucun FETCH dans votre boucle, @@FETCH_STATUS ne changera jamais de valeur !
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/05/2011, 10h55   #5
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Citation:
Envoyé par aieeeuuuuu
votre WHILE n'étant pas immédiatement suivi d'un BEGIN
Bien vu
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 14h47   #6
Membre actif
 
Inscription : mai 2004
Messages : 283
Détails du profil
Informations forums :
Inscription : mai 2004
Messages : 283
Points : 154
Points : 154
Envoyer un message via MSN à cosmos38240
Bonjour,

Bon j'ai résolu le problème grace à vos conseils merci.
Je n'avais pas compris que le FETCH NEXT FROM permettait d'itérer.

Je ne peux pas traduire le besoin fonctionnelle par une seule requete au finale.

En tout cas merci pour votre aide.
cosmos38240 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/05/2011, 15h17   #7
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Citation:
Je ne peux pas traduire le besoin fonctionnelle par une seule requete au finale.
Certes, mais par une suite de requêtes, très probablement

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket 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 13h13.


 
 
 
 
Partenaires

Hébergement Web