Précédent   Forum des professionnels en informatique > Bases de données > Sybase
Sybase Forum sur la base de données Sybase. Avant de poster -> F.A.Q Sybase, Tutoriels Sybase
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 04/04/2007, 10h11   #1
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Par défaut [ASE] Problème étrange avec une procédure stockée

Bonjour,

Voici mon problème :
j'ai une procédure stockée qui permet des mettre à jour un champ dans plusieurs tables.
Mon problème est que pour certaines tables ça marche sans problème et pour d'autres seules quelques lignes sont traitées et aucune erreur n'est retournée.
Si je relance la procédure pour ces tables, quelques lignes sont traitées en plus (par exemple, au premier passage, 2 lignes sont traitées, puis 5, puis 10... c'est complètement aléatoire), de sorte que si je lance la procédure assez de fois, toute la table est traitée.

Est-ce que quelqu'un a déjà eu ce type de problème ? et si oui, d'où cela peut-il venir ?

Merci
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 10h38   #2
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Est-ce que tu as vérifié la valeur du rowcount ?

Code :
1
2
3
 
SET rowcount 0
go
Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 10h57   #3
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Merci, mais ça ne change rien...

Une autre idée ?
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 11h08   #4
Membre confirmé
 
Homme
Développeur informatique
Inscription : octobre 2006
Messages : 181
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : octobre 2006
Messages : 181
Points : 267
Points : 267
Peux tu nous synthétiser ta proc avec des noms parlant comme Table_A ... sans le vocabulaire métier de ton traitement ?
Jean.Cri1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 11h19   #5
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
ok :

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
 
CREATE PROCEDURE proc AS 
BEGIN
	DECLARE @res varchar(255)
	,	@resultat varchar(255)
	,	@id varchar(50)
 
	-- Table1   ==> OK pour cette table
	DECLARE curs CURSOR FOR SELECT id, nom FROM table1
 
	OPEN curs
	FETCH curs INTO @id, @res
 
	WHILE @@SQLSTATUS = 0
	BEGIN
		EXEC gen_champ @res, @resultat OUTPUT	
		UPDATE table1 SET champ = @resultat WHERE id = @id
		FETCH curs INTO @id, @res
	END
 
	CLOSE curs
	DEALLOCATE CURSOR curs
 
        -- ... d'autres tables... 
 
	-- Table5 ==> NON OK
	DECLARE curs CURSOR FOR SELECT id, nom FROM table5
 
	OPEN curs
	FETCH curs INTO @id, @res
 
	WHILE @@SQLSTATUS = 0
	BEGIN
		EXEC gen_champ @res, @resultat OUTPUT
		UPDATE table5 SET champ = @resultat WHERE id = @id
		FETCH curs INTO @id, @res
	END
 
	CLOSE curs
	DEALLOCATE CURSOR curs
 
	-- Table6 ==> OK pour cette table
	DECLARE curs CURSOR FOR SELECT id, nom FROM table6
 
	OPEN curs
	FETCH curs INTO @id, @res
 
	WHILE @@SQLSTATUS = 0
	BEGIN
		EXEC gen_champ @res, @resultat OUTPUT		
		UPDATE table6 SET champ = @resultat WHERE id = @id
		FETCH curs INTO @id, @res
	END
 
	CLOSE curs
	DEALLOCATE CURSOR curs
 
	-- Table7 ==> NON OK
	DECLARE curs CURSOR FOR SELECT nom FROM table7
 
	OPEN curs
	FETCH curs INTO @res
 
	WHILE @@SQLSTATUS = 0
	BEGIN
		EXEC gen_champ @res, @resultat OUTPUT
		UPDATE table7 SET champ = @resultat WHERE nom = @res
		FETCH curs INTO @res
	END
 
	CLOSE curs
	DEALLOCATE CURSOR curs
 
	-- Table8 ==> OK pour cette table
	DECLARE curs CURSOR FOR SELECT id, nom FROM table8
 
	OPEN curs
	FETCH curs INTO @id, @res
 
	WHILE @@SQLSTATUS = 0
	BEGIN
		EXEC gen_champ @res, @resultat OUTPUT
		UPDATE table8 SET champ = @resultat WHERE id = @id
		FETCH curs INTO @id, @res
	END
 
	CLOSE curs
	DEALLOCATE CURSOR curs
 
	-- ... d'autres tables... 
 
	RETURN 0
END
Même si je sors de ma proc les tables concernées (en créant d'autres procédures), j'ai le même problème pour ces tables...

Merci
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 11h26   #6
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Vérifie le code de la proc "gen_champs" - est-ce qu'elle a un "set rowcount" quelque part ?

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 11h34   #7
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Ca ne change rien non plus...

Cette procédure sert juste à remplacer des caractères accentués par des caractères non accentués.

La voici (en partie) :

Code :
1
2
3
4
5
6
7
8
9
 
CREATE PROCEDURE gen_champ (@donnee VARCHAR(255), @sortie VARCHAR(255) OUTPUT) AS 
BEGIN	
	SELECT @donnee = STR_REPLACE(@donnee, '-', '-')
	SELECT @donnee = STR_REPLACE(@donnee, ' ', '-')
	-- ...
 
	SELECT @sortie = LOWER(@donnee)
END
Ce qui m'intrigue le plus, c'est que pour la plupart des tables, tout se passe bien : donc il me semble que le problème ne vient pas des procédures.
Si je lance plusieurs fois le chargement sur les tables traitées en partie, elles finnisent par être completement traitées (et de plus, je n'ai pas d'erreur renvoyée) : donc le problème ne vient pas des tables non plus.
Si j'isole le traitement de ces tables dans une autre procédure, j'ai le même problème : donc pas un problème de mémoire (d'autant plus que ces tables contiennet moins de 1000 lignes).

Donc, d'où vient le problème ???

Merci pour votre aide.
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 11h48   #8
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Si je rajoute un PRINT de @@ROWCOUNT après les FETCH :

exécution1 :
rowcount : 1
rowcount : 2
rowcount : 3
rowcount : 3
(1 row affected)
(return status = 0)

exécution2 :
rowcount : 1
rowcount : 2
rowcount : 3
rowcount : 4
rowcount : 5
rowcount : 5
(1 row affected)
(return status = 0)

exécution3 :
rowcount : 1
rowcount : 2
rowcount : 3
rowcount : 4
rowcount : 5
rowcount : 6
rowcount : 6
(1 row affected)
(return status = 0)

et ainsi de suite...
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 11h49   #9
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Je ne vois pas vraiment où pourrait être le problème - la boucle du fetch par curseur semble correcte.
Un dbcc checktable() de l'une ou l'autre table source serait peut-être judicieux juste pour s'assurer qu'il n'y a pas de corruption.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 12h07   #10
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
le DBCC CHECKTABLE ne donne rien, les tables ne sont pas endomagées...

Merci quand même pour ton aide.
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 12h09   #11
Membre confirmé
 
Homme
Développeur informatique
Inscription : octobre 2006
Messages : 181
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : octobre 2006
Messages : 181
Points : 267
Points : 267
Tu updates une table sur laquelle tu as ouvert un curseur FOR SELECT.

La syntaxe FOR UPDATE couplé avec update table set champ=??? where current of ton_curseur serait peut etre plus adaptée.

Merci de nous tenir au courant.

Le champs mis à jour ne serait il pas dans la clé ou un index ?
Quel est le shema de verrouillage des tables qui posent probleme ?
Jean.Cri1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 12h43   #12
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Je viens de trouver quelque chose : les tables concernées n'ont pas de clé primaire.

En changeant mon curseur en UPDATE et en faisant l'update avec 'where CURRENT OF curs", j'ai l'erreur suivante :

The optimizer could not find a unique index which it could use to scan table 'motcle' for cursor 'curs'.
(return status = -6)


Celà dit, dans la version inotiale du script, je n'utilisait pas de clé puisque je faisait un update sur "id = @id" ou "nom = @res" (id et nom n'étant pas définis comme clé primaires)

Donc ma question : comment faire un update sur des tables sans clé ?

Merci
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 13h19   #13
Membre du Club
 
Inscription : octobre 2005
Messages : 79
Détails du profil
Informations personnelles :
Âge : 32

Informations forums :
Inscription : octobre 2005
Messages : 79
Points : 46
Points : 46
Citation:
Envoyé par ysae17
Je viens de trouver quelque chose : les tables concernées n'ont pas de clé primaire.

En changeant mon curseur en UPDATE et en faisant l'update avec 'where CURRENT OF curs", j'ai l'erreur suivante :

The optimizer could not find a unique index which it could use to scan table 'motcle' for cursor 'curs'.
(return status = -6)


Celà dit, dans la version inotiale du script, je n'utilisait pas de clé puisque je faisait un update sur "id = @id" ou "nom = @res" (id et nom n'étant pas définis comme clé primaires)

Donc ma question : comment faire un update sur des tables sans clé ?

Merci
Pour faire un update via un curseur sur une table sans clés, il faut que le schéma de la table soit en datarows (ce qui identifie de façon unique tes lignes, en résumé tu as un id implicite).

Par contre changer le schéma de ta table n'est peut être pas conseillé, je m'explique cela va solutionner ton problème lié à ton curseur mais risque de te créer d'autres problèmes (accès aux data, etc ...).

Quel est le problème, pourquoi tu ne peux pas mettre une clé ?
lsone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 14h01   #14
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Effectivement, je peux modifier mes tables pour rajouter une clé, mais cette solution est difficilement envisageable car elles sont utilisées par beaucoup d'applications.

Existe-t-il une autre solution ?

(et est-ce que quelqu'un pourrait m'expliquer ce phénomène? Pourquoi lors d'un update d'une table sans clé, seules quelques lignes sont prises en compte, puis un peu plus, et ainsi de suite...?)

Merci
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 14h17   #15
Rédacteur/Modérateur
 
Inscription : janvier 2006
Messages : 1 301
Détails du profil
Informations personnelles :
Âge : 52

Informations forums :
Inscription : janvier 2006
Messages : 1 301
Points : 1 505
Points : 1 505
Envoyer un message via AIM à mpeppler
Le problème c'est que le curseur crée un plan d'exécution, et qu'en updatant la table "sous lui" tu fais en sorte que la suite des lignes à lire devient incorrecte et ASE pense qu'il n'y a plus de lignes à lire.

Michael
__________________
Michael Peppler
Membre de TeamSybase - www.teamsybase.com

"A successful [software] tool is one that was used to do something undreamed of by its author." -- S. C. Johnson
mpeppler est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 14h20   #16
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Ok, je crois que j'ai compris.

Donc normalement, en passant par une table temporaire (avec une clé celle-là) ça devrait être bon.
Je vous tiens au courant.

Merci pour votre aide.
ysae17 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 14h21   #17
Membre confirmé
 
Homme
Développeur informatique
Inscription : octobre 2006
Messages : 181
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : octobre 2006
Messages : 181
Points : 267
Points : 267
A mon avis cela devrait marcher :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	SELECT id,nom INTO #T_curseur
DECLARE curs CURSOR FOR SELECT id, nom FROM #T_curseur
 
	OPEN curs
	FETCH curs INTO @id, @res
 
	WHILE @@SQLSTATUS = 0
	BEGIN
		EXEC gen_champ @res, @resultat OUTPUT
		UPDATE table5 SET champ = @resultat WHERE id = @id
		FETCH curs INTO @id, @res
	END
 
	CLOSE curs
	DEALLOCATE CURSOR curs
Et la, le curseur étant décorrelé de la table updatée , je pense que tu ne devrais plus avoir de probleme.
Jean.Cri1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 14h26   #18
Membre du Club
 
Inscription : octobre 2005
Messages : 79
Détails du profil
Informations personnelles :
Âge : 32

Informations forums :
Inscription : octobre 2005
Messages : 79
Points : 46
Points : 46
Citation:
Envoyé par ysae17
Bonjour,

Voici mon problème :
j'ai une procédure stockée qui permet des mettre à jour un champ dans plusieurs tables.
Mon problème est que pour certaines tables ça marche sans problème et pour d'autres seules quelques lignes sont traitées et aucune erreur n'est retournée.
Si je relance la procédure pour ces tables, quelques lignes sont traitées en plus (par exemple, au premier passage, 2 lignes sont traitées, puis 5, puis 10... c'est complètement aléatoire), de sorte que si je lance la procédure assez de fois, toute la table est traitée.

Est-ce que quelqu'un a déjà eu ce type de problème ? et si oui, d'où cela peut-il venir ?

Merci
Pour utiliser un curseur sur une table celle ci doit :
- soit avoir un clé
- soit un schéma datarow

Si vous ne respectez pas ces conditions vous obtenez des comportements aléatoire car le curseur n'a pas de moyens pour identifier les enregistrements de façon unique.
lsone est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/04/2007, 14h34   #19
Invité de passage
 
Inscription : janvier 2006
Messages : 12
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 12
Points : 2
Points : 2
Ca marche !

Merci à tous pour votre aide.
ysae17 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 01h17.


 
 
 
 
Partenaires

Hébergement Web