Contrainte d'intégrité impossible ? [SGBDR] - SQL/NoSQL - Programmation
Marsh Posté le 10-03-2004 à 10:17:40
Pas d'autre solution que de faire un trigger (au minimum).
Un trigger sur INSERT et UPDATE de la table des prix, qui va vérifier que le prix saisi est supérieur ou égal à ton calcul.
Je verrais bien d'autres trigger, afin de mettre à jour le prix (ou planter) quand tu INSERT ou UPDATE le temps de production d'un élément, le prix à la journée d'un atelier, etc et que le nouveau prix est suppérieur au prix de vente.
A noter toutefois : Les triggers c'est un truc de fac, et extrêment rarement utilisé sur des environnements de production, sauf cas critiques, ou cas bien spécifiques (création d'un ID auto-incrément à partir d'une séquence par exemple). En effet, cela ralenti considérablement toutes les modifications des données, puisqu'ils sont éxécutés A LA LIGNE (à moins que comme SQL Server le permet, tu crées un trigger global pour toutes les lignes modifiées d'un coup, mais dans ce cas, il acceptera toutes les lignes, ou les rejettera toutes, ce qui n'est pas forcément ce que tu veux...)
Marsh Posté le 10-03-2004 à 23:30:21
C'est en effet la solution la plus courrante.
Après, pour une raison de garantie de l'intégrité, c'est moins bien, mais niveau perfs, ça fait en effet la différence, donc sur le monde du travail tu verras que les triggers sont "jamais" utilisés.
Marsh Posté le 10-03-2004 à 23:42:07
Pour les profs à la fac, oui
Nan, sérieux, les triggers sont très peu utilisés, mais on en utilise quand même, pour les trucs sensibles.
pour les stocks par exemple : dès qu'une commande est passée, les stocks sont généralement mis à jour par trigger, histoire de ne pas permettre de passer une commande si la mise à jour des stocks échoue.
mais c'est surtout les procédures stockées entre autre qui sont très utilisées
Marsh Posté le 12-03-2004 à 11:18:19
question subsidiaire : si on utilise pas les triggers, on gère comment le fait d'avoir une clé unique générée (dans mon exemple on doit gérer des commandes, et chaque commande doit pouvoir etre identifiée de manière unique...il faut donc qu'au moment où elle soit rentrée dans la base la clé soit unique...le prof nous a proposé un trigger qui génére le next_ID...g pensé au timestamp, qui lui aussi est supposé etre unique...mais est-ce qu'un timestamp peut constituer une clé unique ?
Marsh Posté le 12-03-2004 à 11:33:35
Clé unique = Clé primaire (ou secondaire) = Index unique, clustered si aucun index clustered déjà présent.
Sous Oracle par exemple, on crée très rarement de clé primaire sur une table, on se contente de faire un index unique dessus.
Ce dernier va garantir l'unicité des données sans nécessiter un trigger (la requête plantera en cas de doublon, et ce, sans devoir vérifier les données au préalable, juste l'index, donc bien plus rapide)
Si tu veux associer un ID unique à ce champ, alors deux solutions :
- Créer une séquence (Oracle, PostGre, etc.) plus un trigger, qui s'occupe UNIQUEMENT de mettre la nouvelle valeur de la séquence à la place de l'ID quand il n'est pas renseigné.
- Créer un champ de type "numéro auto" (MySQL, Access) ou de type Identity avec un incrément de 1 (SQL Server 2000)
- Créer un champ de type "uniqueID" avec comme valeur par défaut "=newUniqueID()" (SQL Server 2000)
A noter que la dernière solution est pas mal pour gérer par exemple des comptes utilisateurs, ou toute autre donnée sensible dont tu veux empêcher la déduction de l'ID.
Unique ID est une série de chiffres sur 72 bits, générés aléatoirement. Après un rapide calcul, on s'apperçoit qu'un processeur cadencé à 3 GHz, à compter qu'il est capable de générer un tel chiffre en un seul cycle (ce qui est faux) et qui passe sont temps à ne faire que ça, va mettre quelques millions d'années pour avoir une chance sur 1000 de générer un doublon. Donc ce type de données, donc l'unicité n'est pas garantie, et tout de même réputé unique. L'avantage, c'est que t'as pas de séquence 1, 2, 3, 4, qu'un hacker peut aisément tenter d'exploiter pour se faire passer par un autre utilisateur par exemple. Là, il a lui aussi une chance sur nbLignes / 2*^72 de trouver un ID déjà existant par hasard, donc ne peut utiliser ce genre de failles.
En contre-partie, 72 bits c'est plus lourd à gérer par le moteur de la base de données qu'un 32 bits (integer)
Marsh Posté le 12-03-2004 à 11:37:09
je suis sous interbase...faudrait que je regarde si y ont un champs auto-incrémental...
ca me semble compliqué (je débute aussi)...on nous apprend bien gentiement avec les clé unique + foreign key + constraints (check surtout)
Marsh Posté le 12-03-2004 à 11:38:54
Jubijub a écrit : je suis sous interbase...faudrait que je regarde si y ont un champs auto-incrémental... |
Nan, faudra faire un trigger
Marsh Posté le 12-03-2004 à 16:32:02
Yep, mais un trigger qui se contente d'attribuer un numéro. En aucun cas tu vérifies avant l'existence de la ligne, tu laisses faire ton index unique pour ça.
Marsh Posté le 10-03-2004 à 08:50:41
Salut...j'ai un projet à la fac dans lequel je voudrais mettre une contrainte d'intégrité assez complexe (je sais même pas si c possible)
Les tables concernées sont :
TABLE COMPOSANT :
#code_composant
designation
quantite_en_stock
cout_unitaire
FK code_fournisseur (references Fournisseurs.code_fournisseur)
TABLE ASSEMBLAGE :
FK code_produit (references Produits.code_produits)
FK code_composant (references Composants.code_composant)
FK code_atelier (references Atelier.code_atelier)
quantite_requise
duree
TABLE PRODUITS :
# code_produit
desigantion
prix_vente_unitaire
delai_fabrication
TABLE Atelier :
#code_atelier
designation
cout_fonct_jour
(c simplet comme exemple hein, je sais, je débute)
On est libre sur les requetes à faire et les contraintes, et on a décidé d'orienter ca gestion de la prod/gestion de stock.
C'est destiné à etre piloté via une UI Java/SWING, donc on aura un accès fin aux données et à leur traitement de tt façon, mais je voulais pouvoir forcer en dur le maximum de contraintes.
En gros : on considère qu'on va produire des bagnoles. Chaque bagnole a plusieurs composants...
De plus, on considère que le temps d'assemblage d'une voiture est égale au temps d'assemblage du composant le plus long.
Ainsi, le cout de prod est :
Somme des (Assemblage.code_composant * composant.cout_unitaire)
+ Max (Assemblages.durée) pour le produit donné * Atelier.cout_fonct_jour (dans un premier temps on suppose que ce cout est le cout atelier/voiture/jour)
D'un autre coté g le prix de vente-unit dans PRODUITS...
La contrainte que je voudrais mettre, c interdire la vente à perte, cad faire que le prix de vente soit supérieur au cout de revient...
et je vois pas du tout comment faire....
---------------
Jubi Photos : Flickr - 500px