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 :

Trigger et suppressions multi-lignes [2016]


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 66
    Points : 45
    Points
    45
    Par défaut Trigger et suppressions multi-lignes
    Bonjour à tous et à toutes;

    Je viens enfin de faire fonctionner mes triggers DELETE, UPDATE et INSERT mais j'ai un souci lors de la suppression multi-lignes du type : DELETE FROM maTable.

    J'explique :
    J'ai deux tables qui sont ECRITURE et CONSOLIDATION; a chaque ajout, suppression ou modification d'une ligne dans la table ECRITURE je veux que la table CONSOLIDATION soit mise à jour. Ecriture par écriture cela fonctionne parfaitement bien pour les INSERT, les UPDATE et les DELETE (trois triggers); mais lorsque j'effectue des modifications multiples dans la table ECRITURE, la table CONSOLIDATION se met partiellement à jour (exemple de la requête : DELETE FROM ECRITURE)

    Voici le code du trigger (traitement après suppression) :
    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
    ALTER TRIGGER [dbo].[MAJ_DELETE] 
       ON  [dbo].[ECRITURE]
       AFTER DELETE
     
    AS 
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        -- Insert statements for trigger here
     
    	DECLARE @Annee int;
    	DECLARE @Mois int;
     
    	--Récupération des valeurs ANNEE et MOIS de la ligne d'ECRITURE supprimée
     
    	SELECT @Annee = E.ANNEE , @mois = E.MOIS FROM deleted E
     
    	--Mise à jour des montants de CREDIT et de DEBIT de la table CONSOLIDATION
     
    	EXECUTE dbo.CONSOLIDATION_MAJ @Mois, @Annee
     
    END
    Voici le code de la procédure stockée CONSOLIDATION_MAJ :

    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
     
    ALTER PROCEDURE [dbo].[CONSOLIDATION_MAJ]
    	-- Add the parameters for the stored procedure here
    	@Mois int,
    	@Annee int
     
    AS
    BEGIN
    	-- SET NOCOUNT ON added to prevent extra result sets from
    	-- interfering with SELECT statements.
    	SET NOCOUNT ON;
     
        -- Insert statements for procedure here
    	UPDATE CONSOLIDATION SET 
    		CREDIT = (SELECT COALESCE(SUM(COALESCE(E.CREDIT, 0)),0) FROM ECRITURE AS E WHERE (E.ANNEE = @Annee and E.MOIS = @mois)),
    		DEBIT = (SELECT COALESCE(SUM(COALESCE(E.DEBIT, 0)),0) FROM ECRITURE AS E WHERE (E.ANNEE = @Annee and E.MOIS = @mois))  
    	WHERE (CONSOLIDATION.ANNEE = @Annee and CONSOLIDATION.MOIS = @mois)
     
    END
    Si quelqu'un peut m'expliquer le problème ça serait super
    Par avance merci;
    Alex01

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Bonjour,
    Quand tu fais un update de plusieurs lignes ta table deleted comprend plusieurs lignes également, si tu veux tu peux les traiter unitairement avec un curseur ou de façon ensembliste.
    Exemple de traitement ensembliste
    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
    UPDATE C
    SET 
       Credit=e1.credit,
       Debit=e1.debit
    from CONSOLIDATION C
    inner join 
    	(	select distinct d1.annee, d1.mois
    		from
    		Deleted d1) d
    	on c.annee=d.annee
    	and c.mois=d.mois
    inner join 
    (
    	select e.Annee, e.Mois, COALESCE(SUM(COALESCE(E.CREDIT, 0)),0) as Credit,
    	COALESCE(SUM(COALESCE(E.DEBIT, 0)),0) Debit
    	from Ecriture e
    	group by e.Annee, e.Mois,
    ) e1
    on d.annee=e1.annee
    and d.mois=e2.mois
    Accessoirement ton trigger ne mettra à jour ta table consolidation qu'en cas de delete, pas en cas d'insert ou d'update
    PS : Ma requete ne donne pas tout à fait le résultat car elle ne remet pas à 0 les mois sans ecriture. A toi d'adapter.
    Cordialement
    Soazig

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    De plus il est inutile de faire trois triggers. Un seul trigger peut être codé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TRIGGER [dbo].[MAJ_ECRITURE] 
       ON  [dbo].[ECRITURE]
       AFTER INSERT, UPDATE,DELETE
    AS
    SET NOCOUNT ON;
    ...
    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/ * * * * *

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 66
    Points : 45
    Points
    45
    Par défaut
    Bonjour et merci de vos réponses;

    Un peu plus inspiré ce matin, je suis finalement passé par les curseurs :

    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
    DECLARE @Annee int;
    	DECLARE @Mois int;
     
    	DECLARE curseur_deleted CURSOR FOR
    	  SELECT E.ANNEE , E.MOIS FROM deleted E;
     
        OPEN curseur_deleted;
     
        FETCH curseur_deleted INTO @Annee, @Mois;
     
        WHILE @@FETCH_STATUS = 0
          BEGIN
            EXECUTE dbo.CONSOLIDATION_MAJ @Mois, @Annee;
            FETCH curseur_deleted INTO @Annee, @Mois;
    	  END
     
        CLOSE curseur_deleted;
        DEALLOCATE curseur_deleted;
    Et là ça fonctionne parfaitement !
    Je vous remercie pour votre assistance ...

    Alex01

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 772
    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 772
    Points : 52 737
    Points
    52 737
    Billets dans le blog
    5
    Par défaut
    Mieux vaut ouvrir votre curseur en mode : LOCAL FORWARD_ONLY STATIC et READ_ONLY sinon vous allez verrouiller et mobiliser beaucoup trop de ressources et potentiellement générer des attentes, des blocages, de la contention et des verrous mortels.

    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/ * * * * *

  6. #6
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour

    Globalement, il serait préférable de transformer la table CONSOLIDATION en vue, et de l'indexer si nécessaire.

    vous pourriez alors vous passer des ces déclencheurs et les performances seraient certainement meilleures

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

Discussions similaires

  1. trigger delete pour plusieurs lignes
    Par Shabata dans le forum Langage SQL
    Réponses: 6
    Dernier message: 30/09/2009, 01h00
  2. Dbgrid : Comment interdire Suppression de Ligne
    Par Francis dans le forum Bases de données
    Réponses: 3
    Dernier message: 28/11/2004, 08h31
  3. Réponses: 4
    Dernier message: 02/07/2004, 19h14
  4. [VB.NET] Suppression de ligne dans un DataTable
    Par seemax dans le forum Windows Forms
    Réponses: 7
    Dernier message: 06/05/2004, 14h19
  5. Multi lignes dans un StringGrids ?
    Par Xavier dans le forum C++Builder
    Réponses: 3
    Dernier message: 27/11/2002, 23h15

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