IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

problème avec curseur "for update"


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    272
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 272
    Points : 114
    Points
    114
    Par défaut problème avec curseur "for update"
    Bonjour tout le monde,

    Je travaille sur SQL server 2005 + Access 2003 et j'ai qql soucis avec un curseur qui est sensé me mettre 2 champs d'une table à jour mais sans succès.

    L'appel de la procédure stockée de mise à jour depuis Access ne pose aucun problème. Le hic est dans SQL Server: il me dit que le curseur que j'utilise est en "READ ONLY", or je spécifie bien "FOR UPDATE" dans la déclaration de mon curseur.

    Voici d'ailleur la procédure stockée en question :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    ALTER PROCEDURE [dbo].[sp_MAJ_pa_pourcentage_pour_validation_ART]
    	@PA_OBJ_FAM_NO AS BIGINT
    AS
    BEGIN
    	SET NOCOUNT ON;
     
    	DECLARE @ART VARCHAR(16)
    	DECLARE @QTE_CALC REAL
    	DECLARE @QTE_AJUST REAL
    	DECLARE @QTE_FINALE REAL
    	DECLARE @QTE_FAM BIGINT
    	DECLARE @POURCENT_NEW REAL
     
    	DECLARE c_ajust_art CURSOR SCROLL FOR
    		SELECT rq_ooep_obj_validArt_qte_pr_ajust.pa_art_cod , tb_OOEP_OBJ_pourcent_art.pa_qte_art_calc, rq_ooep_obj_validArt_qte_pr_ajust.delta_article, tb_OOEP_OBJ_pourcent_art.pa_qte_fam
    		FROM   rq_ooep_obj_validArt_qte_pr_ajust INNER JOIN
                          tb_OOEP_OBJ_pourcent_art ON rq_ooep_obj_validArt_qte_pr_ajust.pa_art_cod = tb_OOEP_OBJ_pourcent_art.pa_art_cod
    		WHERE tb_ooep_obj_pourcent_art.pa_obj_fam_no = @PA_OBJ_FAM_NO
    	FOR UPDATE OF tb_ooep_obj_pourcent_art.pa_qte_art_man, tb_ooep_obj_pourcent_art.pa_pourcentage_man
     
    	-- mise à jour des quantités d'articles. 
    		-- La différence (delta) entre la quantité initiale de la famille et la quantité finale après modification de l'utilisateur
    		-- est répartie ou retranchée entre les différents articles de la famille qui n'ont pas été modifiés.
    	-- calcul et mise à jour du nouveau pourcnetage de répartition des articles par rapport au total de la famille
    	OPEN c_ajust_art
    	FETCH c_ajust_art INTO @ART, @QTE_CALC, @QTE_AJUST, @QTE_FAM
     
    	IF (@@FETCH_STATUS = 0)
    	BEGIN
    		FETCH FIRST FROM c_ajust_art INTO @ART, @QTE_CALC, @QTE_AJUST, @QTE_FAM
    		WHILE @@FETCH_STATUS = 0
    		BEGIN
    			SELECT @QTE_FINALE = @QTE_CALC+@QTE_AJUST  -- calcul de la nouvelle qtt de l'article
    			SELECT @POURCENT_NEW = @QTE_FINALE*100/@QTE_FAM -- calcul du nouveau pourcentage de répartition
    			UPDATE tb_ooep_obj_pourcent_art  -- mise à jour de la table SQL
    			SET pa_qte_art_man = @QTE_FINALE  -- maj de la quantité
    			WHERE CURRENT OF c_ajust_art
    --			UPDATE tb_ooep_obj_pourcent_art
    --				SET pa_pourcentage_man = @POURCENT_NEW -- mise à jour du pourcentage
    --				WHERE CURRENT OF c_ajust_art
     
    			FETCH NEXT FROM c_ajust_art INTO @ART, @QTE_CALC, @QTE_AJUST, @QTE_FAM
    		END
    	END
    	CLOSE c_ajust_art
    	DEALLOCATE c_ajust_art
    END
    Quelqu'un verrait-il pourquoi ma procédure ne s'exécute pas et comment je pourrais changer ce maudit curseur en "FOR UPDATE" et non pas en "READ ONLY)

    Merci et bonne journée à tous

    Julius

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 922
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 922
    Points : 51 715
    Points
    51 715
    Billets dans le blog
    6
    Par défaut
    C'est normal. Vous faites une jointure. De ce fait il y a deux tables dans votre requête SQL qui ouvre le curseur. Or la mise à jour des données ne peut se faire que sur une table à la fois. Par nature ce genre de curseur ne peut JAMAIS être mis à jour.

    D'ailleurs la mise à, jour à travers un curseur est en général une très mauvaise idée !

    La plupart du temps le recours à un curseur est inutile. Depuis la version 2005 de SQL Serveur et donc l'introduction des requêtes récursives, SQL est un langage complet, ce qui fait que n'importe quel traitement quelle que soit sa complexité peut s'effectuer en une seule requête en théorie... Reste bien évidemment à pratiquer !

    A +

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    272
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 272
    Points : 114
    Points
    114
    Par défaut
    Bonjour SQLpro,

    merci pour votre réponse.

    D'ailleurs la mise à, jour à travers un curseur est en général une très mauvaise idée !
    On en apprend tous les jours...

    Je vais donc tenter la chose sans faire de curseur..

    Merci encore et bonne journée

    Julius

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    272
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Janvier 2008
    Messages : 272
    Points : 114
    Points
    114
    Par défaut
    C vrai que c'est tout de même bien plus simple et rapide...

    Du coup je me retrouve avec une simple requête du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    UPDATE
        T1
    SET
        T1.pa_qte_art_man = T1.pa_qte_art_calc + T2.delta_article,
        T1.pa_pourcentage_man = (T1.pa_qte_art_calc + T2.delta_article)*100 / pa_qte_fam
    FROM
        tb_ooep_obj_pourcent_art AS T1 JOIN
        rq_ooep_obj_validArt_qte_pr_ajust AS T2 ON T1.pa_art_cod = T2.pa_art_cod
    WHERE T1.pa_obj_fam_no = 63337
    Merci encore SQLpro pour ces précieux conseils.

    A++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 29/08/2006, 14h59
  2. Problème avec une boucle for
    Par cisse18 dans le forum Général JavaScript
    Réponses: 20
    Dernier message: 29/03/2006, 17h50
  3. [ASE] Les locks avec un cursor for update
    Par PiyuXYZ dans le forum Sybase
    Réponses: 1
    Dernier message: 11/02/2006, 14h17
  4. Formulaires : problème avec les slashes et les quotes
    Par GarGamel55 dans le forum Langage
    Réponses: 1
    Dernier message: 12/10/2005, 16h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo