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 :

Transact-SQL , les triggers


Sujet :

Développement SQL Server

  1. #1
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Transact-SQL , les triggers
    Salut a tous!
    G besion de votre aide!
    En faite g develope un programme de gestion commercial . Aimerai savoir comment ecrire un trigger qui met a jour des lignes d' une colonne. voisi mes exemples de tables au depart avec trigger:
    ---------------------
    table Produit:
    IDProd article
    1 article1
    2 article2
    --------------------
    -------------------------------------------------
    table Commande:
    IDCom - IDProd - QteProdAchete - QteProdRestante
    1 1 150 150
    2 1 200 200
    3 1 100 100
    4 2 50 50
    5 2 70 70
    6 2 80 80
    --------------------------------------------------
    table ProduitVendu:
    IDProdVen -IDProd - QteProdVendu
    1 1 300
    2 2 100
    -----------------------------------------------------
    Alors voici ma question: Comment creer un trigger qu' apres insertion sur la table ProduitVendu va update les lignes de colonne QteProdRestante de la table commande
    en faisant le calcul : (QteProdRestante - QteProdVendu ) puis mettre le resultat a la derniere ligne de la dite colonne parraport au IDProd.
    Donc exple (150+200+100) - 300 = 150 et resultat doit etre :
    -------------------------------------------------
    Commande:
    IDCom - IDProd - QteProdAchete - QteProdRestante
    1 1 150 0
    2 1 200 0
    3 1 100 150
    ------------------------------------------------------
    Merci de votre aide...

  2. #2
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Comment creer un trigger qu' apres insertion sur la table ProduitVendu va update les lignes de colonne QteProdRestante de la table commande
    C'est très simple: ne le créez pas.
    Vous cherchez à stocker une information qui est le fruit d'un calcul... faites ce calcul en temps réel quand vous en avez besoin...

  3. #3
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Comme le dit si bien iberserk, vous n'avez pas besoin de créer un trigger pour cela.
    Les triggers sont conçus pour implémenter des règles métier complexes.
    Il faut également noter que les triggers allongent les transactions, que l'on veut autant que c'est possible faire s'exécuter dans le temps le plus court possible.

    Si vous pensez devoir mettre à jour cette quantité à partir de plusieurs autres procédures stockées, crééz donc une procédure stockée qui se charge seulement de la mise à jour de cette colonne.
    Vous pourrez ainsi l'appeler dans d'autres procédures stockées.

    Si vous n'avez qu'une seule procédure stockée qui ajoute des lignes dans la table Commande, et que vous pensez qu'il y a de faibles chances que vous ayez d'autres procédures stockées qui fassent de même, alors faites tout le calcul dans cette procédure stockée.

    Si vous restez sur une seule procédure stockée pour le moment, voici ce que vous pourriez écrire :

    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
    CREATE PROCEDURE usp_ProduitVendu_ajouter
    	@_IDProd int
    	, @_QteProdVendu int
    AS
    BEGIN
    	SET NOCOUNT ON
     
    	INSERT	dbo.ProduitVendu
    	(
    		IDProd
    		, QteProdVendu
    	)
    	VALUES
    	(
    		@_IDProd
    		, @_QteProdVendu
    	)
     
    	;WITH
    		CTE AS
    		(
    			SELECT	MAX(IDCom) AS last_IDCom_IDProd
    			FROM	dbo.Commande
    			WHERE	IDProd = @_IDProd
    		)
    	UPDATE	dbo.Commande
    	SET	QteProdRestante = QteProdRestante - @_QteProdVendu
    	FROM	dbo.Commande AS C
    	JOIN	CTE AS T ON C.IDCom = T.last_IDCom_IDProd
    	WHERE	IDProd = @_IDProd
    END
    @++

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 849
    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 849
    Points : 52 978
    Points
    52 978
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par iberserk Voir le message
    C'est très simple: ne le créez pas.
    Vous cherchez à stocker une information qui est le fruit d'un calcul... faites ce calcul en temps réel quand vous en avez besoin...
    Mieux, utilisez des vues !!!!

    Normalement on ne devrait jamais développer d'application qu'avec des vues et non pas directement en accédant aux tables ce qui est aberrant !

    A +

  5. #5
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut Merci pour tous vos conseils
    En faite mon probleme est resoulu partiellement, car je veux que les lignes qu' ils ont ete deja traiter prennent la valeur 0; comme ca par exemple:
    -------------------------------------------------------
    Commande:
    IDCom - IDProd - QteProdAchete - QteProdRestante
    1 1 150 0
    2 1 200 0
    3 1 100 150
    ------------------------------------------------------

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 849
    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 849
    Points : 52 978
    Points
    52 978
    Billets dans le blog
    6
    Par défaut
    Encore une fois, faites une vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE VIEW V_COMMANDE_SOLDE
    AS
    SELECT IDCom, IDProd, QteProdAchete, 
           CASE WHEN QteProdRestante - QteProdVendu < 0 THEN 0
                ELSE QteProdRestante - QteProdVendu
           END AS QteProdRestante
    FROM   Commande AS C
           LEFT OUTER JOIN ProduitVendu AS PV
                ON C.IDProd  = PV.IDProd;
    Vous pouvez même insérez, modifier ou supprimer les données à travers les vues ...

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    INSERT INTO V_COMMANDE_SOLDE (IDCom, IDProd, QteProdAchete)
    VALUES (4, 14, 50);
    A +

  7. #7
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Je crois que je m' explique mal.
    IDProd QteProdRestante
    1 15
    2 12
    3 25
    alors le resultat que je veus obtenir apres insertion de de QteProdVendu = 21 soit l' update suivant:
    IDProd QteProdRestante
    1 0
    2 0
    3 31

    ou ceci
    IDProd QteProdRestante
    1 31
    2 0
    3 0

    Bref que le resultat de la soustraction (15+12+25)-21=31 soit place a un des champs de QteProdRestante et le reste des champs prennent la valeur o. Car meme avec la procedure donc vous m avez donne ,ca update le dernier champ mais les autres champs gardent leur valeurs de depart et avec la vue j' obteins les valeurs 0 sur tous les champs.

    Merci .
    Mes excuses pour le derangement .

  8. #8
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Dans ce cas il est clair que la solution de SQLPro est à tous points de vue la plus intelligente.

    Si néanmoins vous souhaitez utiliser la procédure stockée, il vous faudrait la changer en :

    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
    CREATE PROCEDURE usp_ProduitVendu_ajouter
    	@_IDProd int
    	, @_QteProdVendu int
    AS
    BEGIN
    	SET NOCOUNT ON
     
    	INSERT	dbo.ProduitVendu
    	(
    		IDProd
    		, QteProdVendu
    	)
    	VALUES
    	(
    		@_IDProd
    		, @_QteProdVendu
    	)
     
    	DECLARE @last_IDCom_IDProd int
    	SELECT	last_IDCom_IDProd = MAX(IDCom) AS last_IDCom_IDProd
    	FROM	dbo.Commande
    	WHERE	IDProd = @_IDProd
     
    	UPDATE	dbo.Commande
    	SET	QteProdRestante = CASE IDCom
    					WHEN last_IDCom_IDProd THEN QteProdRestante - @_QteProdVendu
    					ELSE 0
    				END
    	WHERE	IDProd = @_IDProd
    END
    @++

  9. #9
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Bref que le resultat de la soustraction (15+12+25)-21=31 soit place a un des champs de QteProdRestante et le reste des champs prennent la valeur o.
    oui mais interêt?

  10. #10
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut bonjour
    Citation Envoyé par iberserk Voir le message
    oui mais interêt?
    L interet ce que cette colonne me permet d' affiche le reste total des produit apres chaque vente et aussi du fait qu' apres une nouvelle insertion des commandes que celle-ci ne s' addition plus avec des restes deja vendus.
    C' est ca tout l' interet de cette colonne...

  11. #11
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Il y a une erreur du type :Syntaxe incorrecte vers le mot clé 'AS'. . Comment resoudre ce probleme ?
    Merci

    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
    BEGIN
    	SET NOCOUNT ON
     
    	INSERT	dbo.ProduitVendu
    	(
    		IDProd
    		, QteProdVendu
    	)
    	VALUES
    	(
    		@_IDProd
    		, @_QteProdVendu
    	)
     
    	DECLARE @last_IDCom_IDProd int
    	SELECT	last_IDCom_IDProd = MAX(IDCom) AS last_IDCom_IDProd
    	FROM	dbo.Commande
    	WHERE	IDProd = @_IDProd
     
    	UPDATE	dbo.Commande
    	SET	QteProdRestante = CASE IDCom
    					WHEN last_IDCom_IDProd THEN QteProdRestante - @_QteProdVendu
    					ELSE 0
    				END
    	WHERE	IDProd = @_IDProd
    END

  12. #12
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    DECLARE @last_IDCom_IDProd int
    SELECT last_IDCom_IDProd = MAX(IDCom) AS last_IDCom_IDProd
    FROM dbo.Commande
    WHERE IDProd = @_IDProd
    Simple...le mot clé AS est interdit ici lors d'une affectation de variable


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT	last_IDCom_IDProd = MAX(IDCom)
    FROM	dbo.Commande
    WHERE	IDProd = @_IDPro

  13. #13
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Simple...le mot clé AS est interdit ici lors d'une affectation de variable


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT	last_IDCom_IDProd = MAX(IDCom)
    FROM	dbo.Commande
    WHERE	IDProd = @_IDPro
    mais le truc ce que s' il y a plus AS alors ca me donne : Nom de colonne non valide*: 'last_IDCom_IDProd'.

  14. #14
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    mais le truc ce que s' il y a plus AS alors ca me donne : Nom de colonne non valide*: 'last_IDCom_IDProd'.
    Car la colonne dans votre table commande ne s'appelle pas mais IDCom mais last_IDCom_IDProd...

    D'où:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT	last_IDCom_IDProd = MAX(AS last_IDCom_IDProd)
    FROM	dbo.Commande
    WHERE	IDProd = @_IDProd
    Mais vous allez avoir un problème.... en effet je me doute que vous voulez assigner cette valeur à la variable @last_IDCom_IDProd...

    Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT	@last_IDCom_IDProd = MAX(AS last_IDCom_IDProd)
    FROM	dbo.Commande
    WHERE	IDProd = @_IDProd

  15. #15
    Futur Membre du Club
    Inscrit en
    Novembre 2010
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Novembre 2010
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par iberserk Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT	@last_IDCom_IDProd = MAX(AS last_IDCom_IDProd)
    FROM	dbo.Commande
    WHERE	IDProd = @_IDProd
    Ca pas changer ca donne tjour: Syntaxe incorrecte vers le mot clé 'as'.

  16. #16
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Je suis désolé pour mon erreur, mais on peut pas dire que vous cherchiez beaucoup ... :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT	@last_IDCom_IDProd = MAX(IDCom)
    FROM	dbo.Commande
    WHERE	IDProd = @_IDProd
    On ne peut pas aliaser une colonne dans une affectation de valeur à une variable.

    @++

  17. #17
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    L interet ce que cette colonne me permet d' affiche le reste total des produit apres chaque vente et aussi du fait qu' apres une nouvelle insertion des commandes que celle-ci ne s' addition plus avec des restes deja vendus.
    C' est ca tout l' interet de cette colonne...

    Je maintiens que c'est une valeur issue d'un calcul... faites une vue comme vous le préconise SQL PRO dans lequel vous faites le calcul 'en temps réel'

  18. #18
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Il est clair que c'est LA solution

    @++

Discussions similaires

  1. Aide pour les transactions SQL server
    Par Carmagamemnon dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 16/01/2009, 11h25
  2. Question sur les performance d'une transaction SQL
    Par SlashEne dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 24/04/2008, 22h41
  3. Syntaxe Trigger Mysql / Transact SQL de SQL Server
    Par Flashball dans le forum SQL Procédural
    Réponses: 8
    Dernier message: 13/03/2008, 15h23
  4. les triggers, pl/sql
    Par ralcoc dans le forum PL/SQL
    Réponses: 2
    Dernier message: 30/06/2006, 05h46

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