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 :

Suppression de masse sans curseur


Sujet :

Développement SQL Server

  1. #1
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 996
    Par défaut Suppression de masse sans curseur
    Bonjour à tous,

    je me frotte à un problème que je ne parviens pas à résoudre seul. Je fais donc appel à vous.
    Je dispose d'une procédure stockée de suppression d'objets dans plusieurs tables liées.
    Cette procédure stockée prend un paramètre en entrée.
    Je veux procéder à une suppression de masse en utilisant cette procédure stockée mais si possible sans curseur car les performances sont vraiment mauvaises (je suis sur plusieurs centaines de milliers d'itérations).

    Voilà comment je procède par curseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    DECLARE @ID uniqueidentifier
    DECLARE BadCursor CURSOR FOR 
    SELECT t.[ID] FROM [dbo].[MATABLE] t WHERE t.[CONDITION] = 1
    FETCH NEXT FROM BadCursor INTO @ID
    WHILE (@@fetch_status <> -1)
    	BEGIN  
    		EXEC MaProcedureStockee @ID
    	END
    	FETCH NEXT FROM BadCursor INTO @ID
    END
    CLOSE BadCursor  
    DEALLOCATE BadCursor
    Je souhaite si possible conserver l'appel à la procédure stockée utilisée dans le curseur car c'est elle qui s'occupe de la suppression et elle a été validée.

    Existe-t-il un moyen de procéder autrement ? Si oui, pourriez-vous me guider ?

    D'avance merci et bonne journée

  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
    22 002
    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 : 22 002
    Billets dans le blog
    6
    Par défaut
    L'utilisation des curseurs à quelque niveau que ce soit est totalement contre performant. En effet une requête est optimisable. Pas un code itératif...
    En gros avec le curseur vous faite devenir le temps de traitement exponentiel alors qu'avec un e requête et les index qui vont bien vous êtes logarithmique...
    Lisez l'étude de elsuket sur le sujet : http://blog.developpez.com/elsuket/p...ecution-entre/

    Donc, il suffit de faire des requêtes DELETE avec sous requête. Exemple
    Tables : T_CLIENT_CLI, T_FACTURE_FAC, T_LIGNE_FACTURE_LIF

    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
    CREATE TRIGGER E_D_CLI
    ON T_CLIENT_CLI
    FOR DELETE
    AS
    -- suppressions dans lignes de facture
    DELETE FROM T_LIGNE_FACTURE_LIF
    WHERE  FAC_ID IN (SELECT FAC_ID
                      FROM   T_FACTURE_FAC
                      WHERE  CLI_ID IN (SELECT CLI_ID
                                        FROM   deleted));
    IF @@ERROR <> 0 
       GOTO LBL_ERROR;
    -- suppressions dans factures
    DELETE FROM T_FACTURE_FAC
    WHERE  CLI_ID IN (SELECT CLI_ID
                      FROM   deleted));
    IF @@ERROR <> 0 
       GOTO LBL_ERROR;
     
    RETURN;
     
    LBL_ERROR:
    ROLLBACK TRANSACTION;

    Une autre façon est de mettre des FOREIGN KEY en mode delete cascade, ce qui ira encore plus vite que la solution par trigger (à des très rares exceptions près, les contraintes sont toujours plus rapide que des triggers).

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Modérateur

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Avril 2007
    Messages
    1 996
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2007
    Messages : 1 996
    Par défaut
    Frédéric,

    merci pour votre réponse.
    J'ai procédé comme vous me le conseillez et ai donc abandonné ma procédure stockée.
    Je fais en fait les suppressions dans les mêmes tables que cette dernière, mais le tout par requête directe.

    Merci pour votre aide.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/10/2006, 10h54
  2. TEdit sans curseur
    Par sanqara dans le forum Composants VCL
    Réponses: 7
    Dernier message: 30/04/2006, 20h39
  3. Traitement ligne par ligne sans curseur
    Par AbyssoS dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 28/02/2006, 17h46
  4. [xslt] Suppression des éléments sans contenu.
    Par dibbouk dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 17/06/2005, 17h17

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