|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||
|
Nouveau Membre du Club
![]() Inscription : juillet 2010 Messages : 196 ![]() |
Bonjour alors voici mon trigger
Code :
Voilà mes tables : consommable (noprod, proddesig, prodprix, qtestock, datemodif, codetype#, reffour#) fournisseur (nofour, libfour, raisonsoc) typeconso (notype, libtype) users(id, login , pass, statut) La base de données est consituée de 4 tables : consommable, fournisseur, typeconso et users : La table consommable contient les différents consommables stockés dans la base de données La table fournisseur répertorie les différents fournisseurs des consommables La table typeconso recense elle les différents types de consommables Enfin, la table users stocke les différents utilisateurs et leurs droits. Le problème ne semble pas venir de mon trigger mais du fait que j'ai mis une clé étrangère entre ces 2 tables. Quand je lenleve la suppression se fait et le trigger sexecute. Comment faire pour que cela fonctionne sans que je n'ai à enlever cette clé étrangère ?Faire une suppression en cascade, chose que je ne sais pas faire avec sqlserver... Merci d'avance ! |
||
|
|
00
|
|
|
#2 | ||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Bonjour,
En effet, le suppression en cascade peut etre une bonne solution dans votre cas. Quelle est votre version de SQL Server ? (il me semble que cette fonctionnalité date de 2005 ?!?) Vous pouvez alors ajouter "ON DELETE CASCADE" à la fin de votre définition de clef étrangère. Cependant, il est normal également que votre trigger ne fonctionne pas : Vous spécifiez un trigger "FOR DELETE", qui s’exécute donc après que la suppression a eu lieu, et donc après que les contraintes d’intégrité ont été vérifiées ! Dans votre cas, la suppression du fournisseur viole une contrainte d'integrité, votre ordre est donc annulé, et votre trigger n'est jamais executé. Pour qu'il fonctionne tel que vous l'avez écrit, vous devriez faire un trigger INSTEAD OF, qui supprime d'abord les consommables, puis supprime les fournisseurs. Pensez également qu'un ordre DELETE peut affecter plusieurs lignes, dans votre trigger, vous cherchez l'ID du fournisseur. Vous devriez donc plutôt faire une suppression directement à partir de la pseudo Table deleted : Code SQL :
|
||
|
|
10
|
|
|
#3 |
|
Nouveau Membre du Club
![]() Inscription : juillet 2010 Messages : 196 ![]() |
Tout d'abord merci pour votre réponse très complète.
Vous me proposez deux solutions. Dois-je les appliquer toutes les deux ou une seule des deux suffit ? J'entends par là que si je rajouter le on delete cascad cela suffira ou alors il faut que jemodifie aussi mon trigger ? Merci d'avance ! |
|
|
00
|
|
|
#4 | ||
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 668 ![]() |
Bonjour,
Citation:
Citation:
Aieeeuuuuu a voulu vous expliquer pourquoi votre trigger ne fait pas ce que vous voulez qu'il fasse. Le trigger tel que vous l'avez écrit n'est pas ensembliste : il est donc faux. @++
__________________
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 |
||
|
10
|
|
|
#5 | ||
|
Nouveau Membre du Club
![]() Inscription : juillet 2010 Messages : 196 ![]() |
Ok.
Si j'ajoute la fonction en cascade. Un trigger comme cela irait ? Code :
Comme ça lorsqu'on delete sur ma table fournisseur automatiquement le trigger se lance et on delete les consommables. C'est bien ça ? |
||
|
|
00
|
|
|
#6 | ||||
![]() ![]() ![]() Nicolas SouquetAdministrateur de base de données Inscription : janvier 2005 Messages : 4 668 ![]() |
C'est l'une des deux solutions, mais pas les deux en même temps :
Si vous mettez CASCADE pour vos DELETE dans la contrainte, vous n'avez pas besoin du trigger, et inversement Pour le trigger, on je préfère cette écriture : Code :
Cela signifie que tel quel, les lignes de la table Consommable seront supprimées, mais pas les lignes de la table fournisseur. En ce sens le code complet du trigger devrait être : Code :
Il s'agit juste des jointures que j'ai horreur (mais c'est mon goût) de voir dans une clause WHERE. Enfin le CASCADE sera moins consommateur de ressources que le trigger. Mais lorsque vous supprimerez des lignes de la table Fournisseur, vous supprimerez également toutes les lignes de toutes les tables référençant la table Fournisseur qui ont pour valeur celle de clé primaire des lignes supprimées de la table Fournisseur. Si ceci n'est pas le comportement que vous souhaitez avoir, alors créez le trigger. @++
__________________
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 |
||||
|
10
|
|
|
#7 | ||||
|
Nouveau Membre du Club
![]() Inscription : juillet 2010 Messages : 196 ![]() |
Je vais me pencher plus vers un trigger.
Cependant vous dites : Code :
Je parle de cette partie du trigger Code :
Edit : J'ai une autre question. Mes tables sont « consommable » (noprod, proddesig, prodprix, qtestock, datemodif, codetype#, reffour#) « fournisseur » (nofour, libfour, raisonsoc) En fait j'ai un problème sur un trigger ou je souhaite controler lors de l'emprunt de consommables si la quantité en stock est suffisante pour le nombre de consommables que la personne souhaite empruntée. Le problème est que je ne sais pas trop comment faire pour un update... Pouvez-vous m'aider ? |
||||
|
|
00
|
|
|
#8 | |
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Citation:
|
|
|
|
20
|
|
|
#9 | ||||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
pour votre problème de quantité en stock, il suffit d'ajouter une contrainte CHECK pour vérifier que la quantité en stock est positive :
Code SQL :
Évitez de passer par des triggers lorsque les contraintes peuvent être définies autrement, pour deux raisons principales : 1/ ce sera optimisé, (les contraintes CHECK sont faites pour cela, et ce sera toujours plus performant, aussi bon que soit votre trigger) 2/ le moteur pourra "comprendre" cette contrainte et s'en servir pour optimiser les plans de requête. Ainsi, avec une telle contrainte, et même sur une table de forte volumétrie, pour une requête telle que Code SQL :
|
||||
|
|
10
|
|
|
#10 |
|
Nouveau Membre du Club
![]() Inscription : juillet 2010 Messages : 196 ![]() |
Ok ok merci pour ces précisions je vais essayer de réaliser ça !
|
|
|
00
|
|
|
#11 | |
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Citation:
polux31 peut spécifier la suppression en cascade sur la contrainte de la table consommable, sans pour autant le spécifier également sur la table Facture(par exemple), référençant également fournisseur. 1/ En cas de suppression d'un fournisseur qui a des consommables mais pas de facture, les consommables sont supprimés 2/ En cas de suppression d'un fournisseur qui a des factures, l'ordre est annulé pour violation de contrainte. Je pense qu'un "ON DELETE CASCADE" serait parfait ici, sauf si polux31 veut ajouter des conditions "métier" à la suppression en cascade, dans quel cas il faut en effet passer par un trigger (par exemple ne supprimer les consommables rattachés au fournisseur QUE si le stock est à 0 pour chaque consommable...) |
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com