Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/04/2011, 03h34   #1
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
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...
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2011, 06h39   #2
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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...
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2011, 08h14   #3
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
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 :
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
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2011, 11h19   #4
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 953
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 953
Points : 17 773
Points : 17 773
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 +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2011, 14h41   #5
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
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
------------------------------------------------------
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2011, 17h47   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 953
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 953
Points : 17 773
Points : 17 773
Encore une fois, faites une vue :

Code :
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 :
1
2
INSERT INTO V_COMMANDE_SOLDE (IDCom, IDProd, QteProdAchete)
VALUES (4, 14, 50);
A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2011, 20h32   #7
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
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 .
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 07h07   #8
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
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 :
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
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 09h35   #9
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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?
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 09h52   #10
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
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...
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 10h04   #11
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
Il y a une erreur du type :Syntaxe incorrecte vers le mot clé 'AS'. . Comment resoudre ce probleme ?
Merci

Code :
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
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 10h13   #12
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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 :
1
2
3
4
 
SELECT	last_IDCom_IDProd = MAX(IDCom)
FROM	dbo.Commande
WHERE	IDProd = @_IDPro
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 10h28   #13
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
Citation:
Envoyé par iberserk Voir le message
Simple...le mot clé AS est interdit ici lors d'une affectation de variable


Code :
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'.
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 11h18   #14
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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 :
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 :
1
2
3
4
 
SELECT	@last_IDCom_IDProd = MAX(AS last_IDCom_IDProd)
FROM	dbo.Commande
WHERE	IDProd = @_IDProd
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 11h38   #15
Invité de passage
 
Inscription : novembre 2010
Messages : 11
Détails du profil
Informations forums :
Inscription : novembre 2010
Messages : 11
Points : 1
Points : 1
Citation:
Envoyé par iberserk Voir le message
Code :
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'.
lepolo2oo8 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 18h39   #16
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Je suis désolé pour mon erreur, mais on peut pas dire que vous cherchiez beaucoup ... :

Code :
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.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 18h53   #17
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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'
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/05/2011, 19h03   #18
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 668
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 668
Points : 8 718
Points : 8 718
Il est clair que c'est LA solution

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h27.


 
 
 
 
Partenaires

Hébergement Web