OVH Cloud OVH Cloud

probleme procedure stockée sous sql 2000

15 réponses
Avatar
coolben
Bonjour

Je travaille depuis quelques temps sur SQL Server 200 et j'ai remarqué des
problèmes lorsque j'affecte à un curseur une selection comportant une
jointure.

Lorsque je teste la requete de selection cela fonctionne très bien sous
l'analyseur de requete mais cela bloque ma procédure chaque fois qu'elle est
executée.

Par contre lorsque je definis un top 100 ou plus dans ma procédure, elle
fonctionne tres bien même si la valeur du top est supérieur au nombre de
tuples selectionnés

Je ne comprend pas.
Quelqu'un pourait il m'expliquer ?

Cordialement,
BS

5 réponses

1 2
Avatar
Philippe T [MS]
Bonjour,

Vous pouvez toujours ajouter la clause FAST_FORWARD au niveau de l'ouverture
de votre curseur :

DECLARE cur CURSOR FAST_FORWARD FOR

Par contre, je ne vois pas dans votre cas l'intéret d'un curseur :

UPDATE personne
SET actif = 0
WHERE code_rh NOT IN (SELECT code_rh FROM intra WHERE code_rh is not null)
AND code_rh NOT LIKE '#%'

----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"coolben" wrote in message
news:
Bonjour et merci de votre aide.

Lorsque je teste ma procedure avec votre requete cela me donne une


execution
de la requete en 2s au lieu de 12s avec ma selection.
Je teins a préciser que je n'ai pas pu testé avec des données et que le
resultat de la requete est vide.

Par contre je viens d'écrire une autre procédure et les resultats sotn


plus
que décevant. Voici le code :
CREATE PROCEDURE maj_intra7
AS
BEGIN
-- Mise a jour des personnes ayant un code RH et dont le nom, prenom, ou
entite ont changé
DECLARE @id INT
DECLARE cur CURSOR FOR
select id_per from personne p where code_rh not in (select code_rh from
intra where code_rh is not null) and code_rh not like '#%'
OPEN cur
FETCH cur INTO @id
WHILE @@fetch_Status = 0
BEGIN
UPDATE personne SET actif=0 WHERE id_per=@id
IF @@ERROR <>0
BEGIN
CLOSE cur
DEALLOCATE cur
RETURN
END
FETCH cur INTO @id
END
CLOSE cur
DEALLOCATE cur
END

la selection comporte 1500 qui devrai etre mis a jour en peu de temps.
Lorsque j'arrete la procedure au bout d'une minute seulement 54 tuples


sont
a jour.
Je ne comprend ce qu'il se passe alors que si je lance cette requete avec
l'analyseur :
update personne set actif=0 where code_rh not in (select code_rh from


intra
where code_rh is not null) and code_rh not like '#%'
J'obtiens une mise a jour imédiate (en 1s) des 1500 champs.
Je ne comprend pas quelle est la raison de cette lenteur


"Philippe T [MS]" a écrit :

> Bonjour,
>
> Votre requete source devrait être écrite comme suit :
>
> SELECT TOP 50000 p.id_per, i.code_rh new
> FROM intra i
> INNER JOIN personne p ON i.nom=p.nom AND i.prenom=p.prenom AND
> i.entite=p.entite
> WHERE i.code_rh is not null
> AND i.code_rh NOT IN (SELECT code_rh FROM personne )
>
> ----------------------------------------------------------------------
> Philippe TROTIN - Microsoft Service France
>
> "Jean-Nicolas BERGER" wrote in
> message news:#
> > Au vu de la procédure, j'aurais tendance à essayer soit un CURSOR FOR
> > UPDATE, soit un INSENSITIVE CURSOR.
> > Qu'est-ce que ça donne?
> > JN.
> >
> >
> > "coolben" a écrit dans le message


de
> > news:
> > > Tout a l heure j'ai lancer une procedure qui fais appel a une


selection
> > > par
> > > jointure. Cette selection est vide mais cela a pris 1minute aavtn


que la
> > > procedure ne se termine. Dans ce cas la boucle n'est pas parcouru ce


qui
> > > m'incite a penser que cele ne viens pas de la boucle. QUAnd je lance


la
> > > requete avec l'analyseur, cela prend que 4s, vide ou non.
> > >
> > > Voici ma procédure :
> > >
> > > CREATE PROCEDURE maj_intra2
> > > AS
> > > BEGIN
> > > DECLARE @code_rh VARCHAR(8), @id INT
> > > DECLARE cur CURSOR FOR
> > > select top 50000 p.id_per, i.code_rh new from intra i, personne p


where
> > > i.code_rh not in (select a.code_rh from personne a where
> > > a.code_rh=i.code_rh)
> > > and i.code_rh is not null and i.nom=p.nom and i.prenom=p.prenom and
> > > i.entite=p.entite
> > > OPEN cur
> > > FETCH cur INTO @id,@code_rh
> > > WHILE @@fetch_Status = 0
> > > BEGIN
> > > UPDATE personne SET code_rh=@code_rh WHERE id_per=@id
> > > IF @@ERROR <>0
> > > BEGIN
> > > print @code_rh
> > > CLOSE cur
> > > DEALLOCATE cur
> > > RETURN
> > > END
> > > FETCH cur INTO @id, @code_rh
> > > END
> > > CLOSE cur
> > > DEALLOCATE cur
> > > END
> > > GO
> > >
> > > BS
> > >
> > > "" a écrit :
> > >
> > >> Essaye de mettre un compteur dans ta boucle pour voir ce
> > >> qui se passe...
> > >> >-----Message d'origine-----
> > >> >D'abord merci pour la reponse.
> > >> >
> > >> >J'utilise un FETCH cur INTO @...
> > >> >Je pense que c'est pareil mais j'utilise cette boucle
> > >> pour tous mes
> > >> >procedures meme lorsqu'elles ne contiennent pas de
> > >> requete avec jointure et
> > >> >cela marche tres bien. Je ne comprend pas comment je
> > >> pourrais avoir une
> > >> >boucle infini puisque ma selection est correct sous
> > >> l'analyseur de requete.
> > >> >
> > >> >BS
> > >> >
> > >> >
> > >> >
> > >> >"" a écrit :
> > >> >
> > >> >> Bonjour,
> > >> >>
> > >> >> As tu mis un "FETCH next" quelque part?
> > >> >>
> > >> >> Ce que tu décris est un boucle infini je pense :)
> > >> >>
> > >> >> A toute
> > >> >>
> > >> >> Portekoi
> > >> >>
> > >> >> >-----Message d'origine-----
> > >> >> >Bonjour
> > >> >> >
> > >> >> >Je travaille depuis quelques temps sur SQL Server 200
> > >> et
> > >> >> j'ai remarquÃf© des
> > >> >> >problÃf¨mes lorsque j'affecte Ãf un curseur une
> > >> selection
> > >> >> comportant une
> > >> >> >jointure.
> > >> >> >
> > >> >> >Lorsque je teste la requete de selection cela
> > >> fonctionne
> > >> >> trÃf¨s bien sous
> > >> >> >l'analyseur de requete mais cela bloque ma
> > >> procÃf©dure
> > >> >> chaque fois qu'elle est
> > >> >> >executÃf©e.
> > >> >> >
> > >> >> >Par contre lorsque je definis un top 100 ou plus dans
> > >> ma
> > >> >> procÃf©dure, elle
> > >> >> >fonctionne tres bien mÃfªme si la valeur du top est
> > >> >> supÃf©rieur au nombre de
> > >> >> >tuples selectionnÃf©s
> > >> >> >
> > >> >> >Je ne comprend pas.
> > >> >> >Quelqu'un pourait il m'expliquer ?
> > >> >> >
> > >> >> >Cordialement,
> > >> >> >BS
> > >> >> >
> > >> >> >.
> > >> >> >
> > >> >>
> > >> >.
> > >> >
> > >>
> >
> >
>
>
>


Avatar
bruno reiter [MVP]
Je me demande vraiment si le curseur est utile dans ce cas.

br

"coolben" wrote in message
news:
Bonjour et merci de votre aide.

Lorsque je teste ma procedure avec votre requete cela me donne une


execution
de la requete en 2s au lieu de 12s avec ma selection.
Je teins a préciser que je n'ai pas pu testé avec des données et que le
resultat de la requete est vide.

Par contre je viens d'écrire une autre procédure et les resultats sotn


plus
que décevant. Voici le code :
CREATE PROCEDURE maj_intra7
AS
BEGIN
-- Mise a jour des personnes ayant un code RH et dont le nom, prenom, ou
entite ont changé
DECLARE @id INT
DECLARE cur CURSOR FOR
select id_per from personne p where code_rh not in (select code_rh from
intra where code_rh is not null) and code_rh not like '#%'
OPEN cur
FETCH cur INTO @id
WHILE @@fetch_Status = 0
BEGIN
UPDATE personne SET actif=0 WHERE id_per=@id
IF @@ERROR <>0
BEGIN
CLOSE cur
DEALLOCATE cur
RETURN
END
FETCH cur INTO @id
END
CLOSE cur
DEALLOCATE cur
END

la selection comporte 1500 qui devrai etre mis a jour en peu de temps.
Lorsque j'arrete la procedure au bout d'une minute seulement 54 tuples


sont
a jour.
Je ne comprend ce qu'il se passe alors que si je lance cette requete avec
l'analyseur :
update personne set actif=0 where code_rh not in (select code_rh from


intra
where code_rh is not null) and code_rh not like '#%'
J'obtiens une mise a jour imédiate (en 1s) des 1500 champs.
Je ne comprend pas quelle est la raison de cette lenteur


"Philippe T [MS]" a écrit :

> Bonjour,
>
> Votre requete source devrait être écrite comme suit :
>
> SELECT TOP 50000 p.id_per, i.code_rh new
> FROM intra i
> INNER JOIN personne p ON i.nom=p.nom AND i.prenom=p.prenom AND
> i.entite=p.entite
> WHERE i.code_rh is not null
> AND i.code_rh NOT IN (SELECT code_rh FROM personne )
>
> ----------------------------------------------------------------------
> Philippe TROTIN - Microsoft Service France
>
> "Jean-Nicolas BERGER" wrote in
> message news:#
> > Au vu de la procédure, j'aurais tendance à essayer soit un CURSOR FOR
> > UPDATE, soit un INSENSITIVE CURSOR.
> > Qu'est-ce que ça donne?
> > JN.
> >
> >
> > "coolben" a écrit dans le message


de
> > news:
> > > Tout a l heure j'ai lancer une procedure qui fais appel a une


selection
> > > par
> > > jointure. Cette selection est vide mais cela a pris 1minute aavtn


que la
> > > procedure ne se termine. Dans ce cas la boucle n'est pas parcouru ce


qui
> > > m'incite a penser que cele ne viens pas de la boucle. QUAnd je lance


la
> > > requete avec l'analyseur, cela prend que 4s, vide ou non.
> > >
> > > Voici ma procédure :
> > >
> > > CREATE PROCEDURE maj_intra2
> > > AS
> > > BEGIN
> > > DECLARE @code_rh VARCHAR(8), @id INT
> > > DECLARE cur CURSOR FOR
> > > select top 50000 p.id_per, i.code_rh new from intra i, personne p


where
> > > i.code_rh not in (select a.code_rh from personne a where
> > > a.code_rh=i.code_rh)
> > > and i.code_rh is not null and i.nom=p.nom and i.prenom=p.prenom and
> > > i.entite=p.entite
> > > OPEN cur
> > > FETCH cur INTO @id,@code_rh
> > > WHILE @@fetch_Status = 0
> > > BEGIN
> > > UPDATE personne SET code_rh=@code_rh WHERE id_per=@id
> > > IF @@ERROR <>0
> > > BEGIN
> > > print @code_rh
> > > CLOSE cur
> > > DEALLOCATE cur
> > > RETURN
> > > END
> > > FETCH cur INTO @id, @code_rh
> > > END
> > > CLOSE cur
> > > DEALLOCATE cur
> > > END
> > > GO
> > >
> > > BS
> > >
> > > "" a écrit :
> > >
> > >> Essaye de mettre un compteur dans ta boucle pour voir ce
> > >> qui se passe...
> > >> >-----Message d'origine-----
> > >> >D'abord merci pour la reponse.
> > >> >
> > >> >J'utilise un FETCH cur INTO @...
> > >> >Je pense que c'est pareil mais j'utilise cette boucle
> > >> pour tous mes
> > >> >procedures meme lorsqu'elles ne contiennent pas de
> > >> requete avec jointure et
> > >> >cela marche tres bien. Je ne comprend pas comment je
> > >> pourrais avoir une
> > >> >boucle infini puisque ma selection est correct sous
> > >> l'analyseur de requete.
> > >> >
> > >> >BS
> > >> >
> > >> >
> > >> >
> > >> >"" a écrit :
> > >> >
> > >> >> Bonjour,
> > >> >>
> > >> >> As tu mis un "FETCH next" quelque part?
> > >> >>
> > >> >> Ce que tu décris est un boucle infini je pense :)
> > >> >>
> > >> >> A toute
> > >> >>
> > >> >> Portekoi
> > >> >>
> > >> >> >-----Message d'origine-----
> > >> >> >Bonjour
> > >> >> >
> > >> >> >Je travaille depuis quelques temps sur SQL Server 200
> > >> et
> > >> >> j'ai remarquÃf© des
> > >> >> >problÃf¨mes lorsque j'affecte Ãf un curseur une
> > >> selection
> > >> >> comportant une
> > >> >> >jointure.
> > >> >> >
> > >> >> >Lorsque je teste la requete de selection cela
> > >> fonctionne
> > >> >> trÃf¨s bien sous
> > >> >> >l'analyseur de requete mais cela bloque ma
> > >> procÃf©dure
> > >> >> chaque fois qu'elle est
> > >> >> >executÃf©e.
> > >> >> >
> > >> >> >Par contre lorsque je definis un top 100 ou plus dans
> > >> ma
> > >> >> procÃf©dure, elle
> > >> >> >fonctionne tres bien mÃfªme si la valeur du top est
> > >> >> supÃf©rieur au nombre de
> > >> >> >tuples selectionnÃf©s
> > >> >> >
> > >> >> >Je ne comprend pas.
> > >> >> >Quelqu'un pourait il m'expliquer ?
> > >> >> >
> > >> >> >Cordialement,
> > >> >> >BS
> > >> >> >
> > >> >> >.
> > >> >> >
> > >> >>
> > >> >.
> > >> >
> > >>
> >
> >
>
>
>


Avatar
coolben
Cela va effectivement plus vite (12 secondes).
Je suis aussi d'accord que ma fonction est n'est pas la plus simple mais
j'ai repris une fonction existant avant de m'apercevoir qu'il etait plus
simple de faire autrement.
SI j'ai bien compris le probleme, lorsque je declare des curseurs, les mises
à jour des données ralentisent la procédure puisqu'il réactualise la requete
apres chaque update.
Lorsque j'utilise des curseurs pour selectionner les lignes cibles et les
modifer, je dois utiliser l'option FAST_FORWARD ou STATIC pour aller plus
vite.
C'est bien ca ?

"Philippe T [MS]" a écrit :

Bonjour,

Vous pouvez toujours ajouter la clause FAST_FORWARD au niveau de l'ouverture
de votre curseur :

DECLARE cur CURSOR FAST_FORWARD FOR

Par contre, je ne vois pas dans votre cas l'intéret d'un curseur :

UPDATE personne
SET actif = 0
WHERE code_rh NOT IN (SELECT code_rh FROM intra WHERE code_rh is not null)
AND code_rh NOT LIKE '#%'

----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"coolben" wrote in message
news:
> Bonjour et merci de votre aide.
>
> Lorsque je teste ma procedure avec votre requete cela me donne une
execution
> de la requete en 2s au lieu de 12s avec ma selection.
> Je teins a préciser que je n'ai pas pu testé avec des données et que le
> resultat de la requete est vide.
>
> Par contre je viens d'écrire une autre procédure et les resultats sotn
plus
> que décevant. Voici le code :
> CREATE PROCEDURE maj_intra7
> AS
> BEGIN
> -- Mise a jour des personnes ayant un code RH et dont le nom, prenom, ou
> entite ont changé
> DECLARE @id INT
> DECLARE cur CURSOR FOR
> select id_per from personne p where code_rh not in (select code_rh from
> intra where code_rh is not null) and code_rh not like '#%'
> OPEN cur
> FETCH cur INTO @id
> WHILE @@fetch_Status = 0
> BEGIN
> UPDATE personne SET actif=0 WHERE id_per=@id
> IF @@ERROR <>0
> BEGIN
> CLOSE cur
> DEALLOCATE cur
> RETURN
> END
> FETCH cur INTO @id
> END
> CLOSE cur
> DEALLOCATE cur
> END
>
> la selection comporte 1500 qui devrai etre mis a jour en peu de temps.
> Lorsque j'arrete la procedure au bout d'une minute seulement 54 tuples
sont
> a jour.
> Je ne comprend ce qu'il se passe alors que si je lance cette requete avec
> l'analyseur :
> update personne set actif=0 where code_rh not in (select code_rh from
intra
> where code_rh is not null) and code_rh not like '#%'
> J'obtiens une mise a jour imédiate (en 1s) des 1500 champs.
> Je ne comprend pas quelle est la raison de cette lenteur
>
>
> "Philippe T [MS]" a écrit :
>
> > Bonjour,
> >
> > Votre requete source devrait être écrite comme suit :
> >
> > SELECT TOP 50000 p.id_per, i.code_rh new
> > FROM intra i
> > INNER JOIN personne p ON i.nom=p.nom AND i.prenom=p.prenom AND
> > i.entite=p.entite
> > WHERE i.code_rh is not null
> > AND i.code_rh NOT IN (SELECT code_rh FROM personne )
> >
> > ----------------------------------------------------------------------
> > Philippe TROTIN - Microsoft Service France
> >
> > "Jean-Nicolas BERGER" wrote in
> > message news:#
> > > Au vu de la procédure, j'aurais tendance à essayer soit un CURSOR FOR
> > > UPDATE, soit un INSENSITIVE CURSOR.
> > > Qu'est-ce que ça donne?
> > > JN.
> > >
> > >
> > > "coolben" a écrit dans le message
de
> > > news:
> > > > Tout a l heure j'ai lancer une procedure qui fais appel a une
selection
> > > > par
> > > > jointure. Cette selection est vide mais cela a pris 1minute aavtn
que la
> > > > procedure ne se termine. Dans ce cas la boucle n'est pas parcouru ce
qui
> > > > m'incite a penser que cele ne viens pas de la boucle. QUAnd je lance
la
> > > > requete avec l'analyseur, cela prend que 4s, vide ou non.
> > > >
> > > > Voici ma procédure :
> > > >
> > > > CREATE PROCEDURE maj_intra2
> > > > AS
> > > > BEGIN
> > > > DECLARE @code_rh VARCHAR(8), @id INT
> > > > DECLARE cur CURSOR FOR
> > > > select top 50000 p.id_per, i.code_rh new from intra i, personne p
where
> > > > i.code_rh not in (select a.code_rh from personne a where
> > > > a.code_rh=i.code_rh)
> > > > and i.code_rh is not null and i.nom=p.nom and i.prenom=p.prenom and
> > > > i.entite=p.entite
> > > > OPEN cur
> > > > FETCH cur INTO @id,@code_rh
> > > > WHILE @@fetch_Status = 0
> > > > BEGIN
> > > > UPDATE personne SET code_rh=@code_rh WHERE id_per=@id
> > > > IF @@ERROR <>0
> > > > BEGIN
> > > > print @code_rh
> > > > CLOSE cur
> > > > DEALLOCATE cur
> > > > RETURN
> > > > END
> > > > FETCH cur INTO @id, @code_rh
> > > > END
> > > > CLOSE cur
> > > > DEALLOCATE cur
> > > > END
> > > > GO
> > > >
> > > > BS
> > > >
> > > > "" a écrit :
> > > >
> > > >> Essaye de mettre un compteur dans ta boucle pour voir ce
> > > >> qui se passe...
> > > >> >-----Message d'origine-----
> > > >> >D'abord merci pour la reponse.
> > > >> >
> > > >> >J'utilise un FETCH cur INTO @...
> > > >> >Je pense que c'est pareil mais j'utilise cette boucle
> > > >> pour tous mes
> > > >> >procedures meme lorsqu'elles ne contiennent pas de
> > > >> requete avec jointure et
> > > >> >cela marche tres bien. Je ne comprend pas comment je
> > > >> pourrais avoir une
> > > >> >boucle infini puisque ma selection est correct sous
> > > >> l'analyseur de requete.
> > > >> >
> > > >> >BS
> > > >> >
> > > >> >
> > > >> >
> > > >> >"" a écrit :
> > > >> >
> > > >> >> Bonjour,
> > > >> >>
> > > >> >> As tu mis un "FETCH next" quelque part?
> > > >> >>
> > > >> >> Ce que tu décris est un boucle infini je pense :)
> > > >> >>
> > > >> >> A toute
> > > >> >>
> > > >> >> Portekoi
> > > >> >>
> > > >> >> >-----Message d'origine-----
> > > >> >> >Bonjour
> > > >> >> >
> > > >> >> >Je travaille depuis quelques temps sur SQL Server 200
> > > >> et
> > > >> >> j'ai remarquÃf© des
> > > >> >> >problÃf¨mes lorsque j'affecte Ãf un curseur une
> > > >> selection
> > > >> >> comportant une
> > > >> >> >jointure.
> > > >> >> >
> > > >> >> >Lorsque je teste la requete de selection cela
> > > >> fonctionne
> > > >> >> trÃf¨s bien sous
> > > >> >> >l'analyseur de requete mais cela bloque ma
> > > >> procÃf©dure
> > > >> >> chaque fois qu'elle est
> > > >> >> >executÃf©e.
> > > >> >> >
> > > >> >> >Par contre lorsque je definis un top 100 ou plus dans
> > > >> ma
> > > >> >> procÃf©dure, elle
> > > >> >> >fonctionne tres bien mÃfªme si la valeur du top est
> > > >> >> supÃf©rieur au nombre de
> > > >> >> >tuples selectionnÃf©s
> > > >> >> >
> > > >> >> >Je ne comprend pas.
> > > >> >> >Quelqu'un pourait il m'expliquer ?
> > > >> >> >
> > > >> >> >Cordialement,
> > > >> >> >BS
> > > >> >> >
> > > >> >> >.
> > > >> >> >
> > > >> >>
> > > >> >.
> > > >> >
> > > >>
> > >
> > >
> >
> >
> >





Avatar
Philippe T [MS]
Bonjour,

Exactement. Si le jeux d'enregistrement n'est pas modifié par le contenu de
votre curseur (pas de curseur dynamique), le mieux est de mettre cette
clause FAST_FORWARD.

----------------------------------------------------------------------
Philippe TROTIN - Microsoft Service France

"coolben" wrote in message
news:
Cela va effectivement plus vite (12 secondes).
Je suis aussi d'accord que ma fonction est n'est pas la plus simple mais
j'ai repris une fonction existant avant de m'apercevoir qu'il etait plus
simple de faire autrement.
SI j'ai bien compris le probleme, lorsque je declare des curseurs, les


mises
à jour des données ralentisent la procédure puisqu'il réactualise la


requete
apres chaque update.
Lorsque j'utilise des curseurs pour selectionner les lignes cibles et les
modifer, je dois utiliser l'option FAST_FORWARD ou STATIC pour aller plus
vite.
C'est bien ca ?

"Philippe T [MS]" a écrit :

> Bonjour,
>
> Vous pouvez toujours ajouter la clause FAST_FORWARD au niveau de


l'ouverture
> de votre curseur :
>
> DECLARE cur CURSOR FAST_FORWARD FOR
>
> Par contre, je ne vois pas dans votre cas l'intéret d'un curseur :
>
> UPDATE personne
> SET actif = 0
> WHERE code_rh NOT IN (SELECT code_rh FROM intra WHERE code_rh is not


null)
> AND code_rh NOT LIKE '#%'
>
> ----------------------------------------------------------------------
> Philippe TROTIN - Microsoft Service France
>
> "coolben" wrote in message
> news:
> > Bonjour et merci de votre aide.
> >
> > Lorsque je teste ma procedure avec votre requete cela me donne une
> execution
> > de la requete en 2s au lieu de 12s avec ma selection.
> > Je teins a préciser que je n'ai pas pu testé avec des données et que


le
> > resultat de la requete est vide.
> >
> > Par contre je viens d'écrire une autre procédure et les resultats sotn
> plus
> > que décevant. Voici le code :
> > CREATE PROCEDURE maj_intra7
> > AS
> > BEGIN
> > -- Mise a jour des personnes ayant un code RH et dont le nom, prenom,


ou
> > entite ont changé
> > DECLARE @id INT
> > DECLARE cur CURSOR FOR
> > select id_per from personne p where code_rh not in (select code_rh


from
> > intra where code_rh is not null) and code_rh not like '#%'
> > OPEN cur
> > FETCH cur INTO @id
> > WHILE @@fetch_Status = 0
> > BEGIN
> > UPDATE personne SET actif=0 WHERE id_per=@id
> > IF @@ERROR <>0
> > BEGIN
> > CLOSE cur
> > DEALLOCATE cur
> > RETURN
> > END
> > FETCH cur INTO @id
> > END
> > CLOSE cur
> > DEALLOCATE cur
> > END
> >
> > la selection comporte 1500 qui devrai etre mis a jour en peu de temps.
> > Lorsque j'arrete la procedure au bout d'une minute seulement 54 tuples
> sont
> > a jour.
> > Je ne comprend ce qu'il se passe alors que si je lance cette requete


avec
> > l'analyseur :
> > update personne set actif=0 where code_rh not in (select code_rh from
> intra
> > where code_rh is not null) and code_rh not like '#%'
> > J'obtiens une mise a jour imédiate (en 1s) des 1500 champs.
> > Je ne comprend pas quelle est la raison de cette lenteur
> >
> >
> > "Philippe T [MS]" a écrit :
> >
> > > Bonjour,
> > >
> > > Votre requete source devrait être écrite comme suit :
> > >
> > > SELECT TOP 50000 p.id_per, i.code_rh new
> > > FROM intra i
> > > INNER JOIN personne p ON i.nom=p.nom AND i.prenom=p.prenom AND
> > > i.entite=p.entite
> > > WHERE i.code_rh is not null
> > > AND i.code_rh NOT IN (SELECT code_rh FROM personne )
> > >
> >
----------------------------------------------------------------------
> > > Philippe TROTIN - Microsoft Service France
> > >
> > > "Jean-Nicolas BERGER" wrote


in
> > > message news:#
> > > > Au vu de la procédure, j'aurais tendance à essayer soit un CURSOR


FOR
> > > > UPDATE, soit un INSENSITIVE CURSOR.
> > > > Qu'est-ce que ça donne?
> > > > JN.
> > > >
> > > >
> > > > "coolben" a écrit dans le


message
> de
> > > > news:
> > > > > Tout a l heure j'ai lancer une procedure qui fais appel a une
> selection
> > > > > par
> > > > > jointure. Cette selection est vide mais cela a pris 1minute


aavtn
> que la
> > > > > procedure ne se termine. Dans ce cas la boucle n'est pas


parcouru ce
> qui
> > > > > m'incite a penser que cele ne viens pas de la boucle. QUAnd je


lance
> la
> > > > > requete avec l'analyseur, cela prend que 4s, vide ou non.
> > > > >
> > > > > Voici ma procédure :
> > > > >
> > > > > CREATE PROCEDURE maj_intra2
> > > > > AS
> > > > > BEGIN
> > > > > DECLARE @code_rh VARCHAR(8), @id INT
> > > > > DECLARE cur CURSOR FOR
> > > > > select top 50000 p.id_per, i.code_rh new from intra i, personne


p
> where
> > > > > i.code_rh not in (select a.code_rh from personne a where
> > > > > a.code_rh=i.code_rh)
> > > > > and i.code_rh is not null and i.nom=p.nom and i.prenom=p.prenom


and
> > > > > i.entite=p.entite
> > > > > OPEN cur
> > > > > FETCH cur INTO @id,@code_rh
> > > > > WHILE @@fetch_Status = 0
> > > > > BEGIN
> > > > > UPDATE personne SET code_rh=@code_rh WHERE id_per=@id
> > > > > IF @@ERROR <>0
> > > > > BEGIN
> > > > > print @code_rh
> > > > > CLOSE cur
> > > > > DEALLOCATE cur
> > > > > RETURN
> > > > > END
> > > > > FETCH cur INTO @id, @code_rh
> > > > > END
> > > > > CLOSE cur
> > > > > DEALLOCATE cur
> > > > > END
> > > > > GO
> > > > >
> > > > > BS
> > > > >
> > > > > "" a écrit :
> > > > >
> > > > >> Essaye de mettre un compteur dans ta boucle pour voir ce
> > > > >> qui se passe...
> > > > >> >-----Message d'origine-----
> > > > >> >D'abord merci pour la reponse.
> > > > >> >
> > > > >> >J'utilise un FETCH cur INTO @...
> > > > >> >Je pense que c'est pareil mais j'utilise cette boucle
> > > > >> pour tous mes
> > > > >> >procedures meme lorsqu'elles ne contiennent pas de
> > > > >> requete avec jointure et
> > > > >> >cela marche tres bien. Je ne comprend pas comment je
> > > > >> pourrais avoir une
> > > > >> >boucle infini puisque ma selection est correct sous
> > > > >> l'analyseur de requete.
> > > > >> >
> > > > >> >BS
> > > > >> >
> > > > >> >
> > > > >> >
> > > > >> >"" a écrit :
> > > > >> >
> > > > >> >> Bonjour,
> > > > >> >>
> > > > >> >> As tu mis un "FETCH next" quelque part?
> > > > >> >>
> > > > >> >> Ce que tu décris est un boucle infini je pense :)
> > > > >> >>
> > > > >> >> A toute
> > > > >> >>
> > > > >> >> Portekoi
> > > > >> >>
> > > > >> >> >-----Message d'origine-----
> > > > >> >> >Bonjour
> > > > >> >> >
> > > > >> >> >Je travaille depuis quelques temps sur SQL Server 200
> > > > >> et
> > > > >> >> j'ai remarquÃf© des
> > > > >> >> >problÃf¨mes lorsque j'affecte Ãf un curseur une
> > > > >> selection
> > > > >> >> comportant une
> > > > >> >> >jointure.
> > > > >> >> >
> > > > >> >> >Lorsque je teste la requete de selection cela
> > > > >> fonctionne
> > > > >> >> trÃf¨s bien sous
> > > > >> >> >l'analyseur de requete mais cela bloque ma
> > > > >> procÃf©dure
> > > > >> >> chaque fois qu'elle est
> > > > >> >> >executÃf©e.
> > > > >> >> >
> > > > >> >> >Par contre lorsque je definis un top 100 ou plus dans
> > > > >> ma
> > > > >> >> procÃf©dure, elle
> > > > >> >> >fonctionne tres bien mÃfªme si la valeur du top est
> > > > >> >> supÃf©rieur au nombre de
> > > > >> >> >tuples selectionnÃf©s
> > > > >> >> >
> > > > >> >> >Je ne comprend pas.
> > > > >> >> >Quelqu'un pourait il m'expliquer ?
> > > > >> >> >
> > > > >> >> >Cordialement,
> > > > >> >> >BS
> > > > >> >> >
> > > > >> >> >.
> > > > >> >> >
> > > > >> >>
> > > > >> >.
> > > > >> >
> > > > >>
> > > >
> > > >
> > >
> > >
> > >
>
>
>


Avatar
Fred BROUARD
Votre procédure stockée est parfaitement inutile. Une simple requête update avec
sous requête est suffisante. Quelque chose comme :

UPDATE personne
SET code_rh = i.code_rh
FROM intra i
INNER JOIN personne p
ON i.nom = p.nom
AND i.prenom=p.prenom
AND i.entite=p.entite
LEFT OUTER JOIN personne a
ON a.code_rh=i.code_rh
WHARE i.code_rh IS NOT null
AND a.code_rh IS NULL

Dans tous le cas, votre proc stock est un veau à double titre :
1) utilisation d'un curseur (ce qu'il a de pire en SQL)
2) mise à jour déguisée d'une des tables sous jacente au curseur !!!

Le mieux est d'apprendre SQL... Mon site web, comme mon bouquin peuvent vous y
aider.

A +

--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************


coolben a écrit:
Bonjour

Je travaille depuis quelques temps sur SQL Server 200 et j'ai remarqué des
problèmes lorsque j'affecte à un curseur une selection comportant une
jointure.

Lorsque je teste la requete de selection cela fonctionne très bien sous
l'analyseur de requete mais cela bloque ma procédure chaque fois qu'elle est
executée.

Par contre lorsque je definis un top 100 ou plus dans ma procédure, elle
fonctionne tres bien même si la valeur du top est supérieur au nombre de
tuples selectionnés

Je ne comprend pas.
Quelqu'un pourait il m'expliquer ?

Cordialement,
BS



1 2