Merci Ordigil !
Et joyeux Noël à vous aussi !
Merci Ordigil !
Et joyeux Noël à vous aussi !
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Bonjour Ordigil,
Aux prises avec son Mack tri-plex, Bob arrive-t-il quand même à s’avaler un casse-croûte ?
Effectivement, techniquement on pourrait avoir. Dans ces conditions, il faudra prévoir une colonne TransmissionType pour la table TRANSMISSION. Les triggers de la table COMPOSANT_AFFECTATION devront s’assurer qu’un camion ne peut avoir qu’une seule transmission primaire et qu’une seule transmission axillaire. On peut aussi prévoir que l’installation d’une transmission axillaire ne puisse se faire que si le camion est déjà doté d’une transmission primaire, voire au besoin que les deux transmissions viennent de chez le même fabricant...Envoyé par ordigil
Quelle est votre position sur tout ça ?
Compte non tenu du typage des transmissions.
Toujours au sujet du trigger CAMION_HUILE_SUIVI_INSERT_TR, dans la version qui prend en compte le multi inserts.
J’ai effectué un aménagement pour la prise en compte des erreurs commises par l’utilisateur. En effet, supposons qu’il soumette un insert à 10 lignes et que la 3e comporte une erreur. Les deux premières sont acceptées, la 3e est rejetée, mais ce qui est embêtant, c’est que les suivantes passent à la trappe puisqu’on abandonne le traitement du fait du rejet...
Je propose donc une version qui rejette bien la ligne erronée, mais prend en compte le traitement des suivantes. Le trigger devient donc :
CREATE TRIGGER CAMION_HUILE_SUIVI_INSERT_TR ON CAMION_HUILE_SUIVI INSTEAD OF INSERT AS BEGIN DECLARE @CurrentTupleHeading AS VARCHAR(64) = '' + CHAR(13) + CHAR(13) + 'Rappel - Changement d''huile en cours de traitement :' + CHAR(13) DECLARE @CurrentTuple AS VARCHAR(512) ; DECLARE @CamionId AS INT ; DECLARE @CamionVIN AS VARCHAR(24) ; DECLARE @CamionNumber AS VARCHAR(6) ; DECLARE @SerialNumber AS VARCHAR(25) ; DECLARE @PositionId AS INT ; DECLARE @ComposantId AS INT ; DECLARE @ComponentSerialNumberInDataBase AS VARCHAR(25) ; DECLARE @ComposantTypeCode AS CHAR(1) ; DECLARE @ComposantTypeSource AS varchar(12) ; DECLARE @ComposantType AS VARCHAR(12) ; DECLARE @OilChangeDate AS DATE ; DECLARE @OilChangeMilleage AS INT ; DECLARE @trigger as varchar(64) = 'ENGINE_OIL_CHANGE_V_INSERT_TR' DECLARE @EngueuladeDebut as VARCHAR(64) = CHAR(13) + @trigger + ' - Oil change ; ' ; DECLARE @Engueulade as VARCHAR(512) DECLARE @N AS INT ; DECLARE @ErreurDetectee AS CHAR(1) = 'n' DECLARE @CamionNumberInvalide AS CHAR(1) = 'n' DECLARE @TypeComposantInvalide AS CHAR(1) = 'n' DECLARE @OilChangeDateAbsente AS CHAR(1) = 'n' DECLARE @AxlePositionInvalide AS CHAR(1) = 'n' DECLARE @SerialNumberInconnu AS CHAR(1) = 'n' DECLARE @SerialNumberAbsent AS CHAR(1) = 'n' DECLARE @ChangementDejaFait AS CHAR(1) = 'n' ---- pour debug ---- select @trigger as '@trigger' ---- pour debug ---- select '' as INSERTED, * from INSERTED -------------------------------------------------------- -- Le curseur utilisé pour les inserts multiples, -- appliqué à INSERTED : --------------------------------------------------------- DECLARE theCurseur CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR SELECT CamionVIN, CamionNumber, ComposantType, SerialNumber, HuileChangementDate, HuileKm FROM INSERTED ; OPEN theCurseur ---- pour debug ----select 'open csr' ----------------------------------------------------- -- Lecture de la 1re ligne de INSERTED ----------------------------------------------------- FETCH theCurseur INTO @CamionVIN, @CamionNumber, @ComposantTypeSource, @SerialNumber, @OilChangeDate, @OilChangeMilleage ---- pour debug ---- select @@FETCH_STATUS as ' @@FETCH_STATUS' WHILE @@FETCH_STATUS = 0 ------------------------------------------------------------- -- tant que le curseur produit, -- on traite le tuple correspondant de INSERTED ------------------------------------------------------------- BEGIN --- pour debug --- select 'un tour de manège' ---- pour debug ---- select @CamionVIN as '@CamionVIN' ------------------------------------------- -- On entame chaque tour de manège sans -- avoir à hériter des erreurs détectée -- lors du tour précédent. ------------------------------------------- SET @CamionNumberInvalide = 'n' SET @TypeComposantInvalide = 'n' SET @OilChangeDateAbsente = 'n' SET @AxlePositionInvalide = 'n' SET @SerialNumberInconnu = 'n' SET @SerialNumberAbsent = 'n' SET @ChangementDejaFait = 'n' ------------------------------------------------------------------------------ -- Image du tuple en cours ------------------------------------------------------------------------------ SET @CurrentTuple = CHAR(13) + ' CamionVIN = ''' + COALESCE(@CamionVIN, '') + '''' + CHAR(13) + ' CamionNumber = ''' + COALESCE(@CamionNumber, '') + '''' + CHAR(13) + ' ComposantType = ''' + COALESCE(@ComposantTypeSource, '') + '''' + CHAR(13) + ' SerialNumber = ''' + COALESCE(@SerialNumber, '') + '''' + CHAR(13) + ' OilChangeDate = ''' + COALESCE(CAST(@OilChangeDate AS VARCHAR), '') + '''' + CHAR(13) + ' OilChangeMilleage = ''' + COALESCE(CAST(@OilChangeMilleage AS VARCHAR), '') + '''' --- pour debug ---- select @CurrentTuple as '@CurrentTuple' PRINT CHAR(13) + '-----------------------------------' + CHAR(13) + 'Ajout à effectuer :' + CHAR(13) + @CurrentTuple + CHAR(13) + '-----------------------------------' ---------------------------------------- -- Pour la ligne en cours : -- Récup de l'identification du camion -- en fonction de son numéro ---------------------------------------- SET @CamionId = ( SELECT CamionId FROM CAMION WHERE CamionNumber = @CamionNumber ) ; ---- pour debug ---- select @CamionId as '@CamionId' ------------------------------------ -- On s'assure que le camion existe ------------------------------------ IF @CamionId IS NULL BEGIN DECLARE @w AS VARCHAR(48) SET @w = 'Unknow Truck ''' + @CamionNumber + '''' IF @CamionNumber is NULL SET @w = 'Missing truck number' ---- pour debug ---- select @CamionNumber AS '@CamionNumber' ; select @w as '@w' ; SET @Engueulade = @EngueuladeDebut + @w SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple -------- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @CamionNumberInvalide = 'y' SET @ErreurDetectee = 'y' ----------- RETURN END ---- pour debug ---- select @ComposantTypeSource as '@ComposantTypeSource' ------------------------------------------------ -- récup du composant type ------------------------------------------------ SET @ComposantType = ( CASE WHEN LOWER(@ComposantTypeSource) = 'engine' THEN 'e' WHEN LEFT(LOWER(@ComposantTypeSource),5) = 'trans' THEN 't' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '1int' THEN '1INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '2int' THEN '2INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '3int' THEN '3INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '4int' THEN '4INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '5int' THEN '5INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '6int' THEN '6INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '7int' THEN '7INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),4) = '8int' THEN '8INTGAWR' WHEN LEFT(LOWER(@ComposantTypeSource),3) = 'frg' THEN 'frgawr' WHEN LEFT(LOWER(@ComposantTypeSource),4) = 'rear' THEN 'reargawr' WHEN LOWER(@ComposantTypeSource) = 'tag' THEN 'tag' ELSE '?' END ) ---- pour debug ---- select @ComposantType as '@ComposantType' -------------------------------------------------- -- si le type de composant est foireux, on dégage -- (comme doit faire le môme de l'Elysée) -------------------------------------------------- IF @ComposantType = '?' BEGIN SET @Engueulade = @EngueuladeDebut + ' camion ''' + @CamionNumber + ''' : Invalid component type ''' + @ComposantTypeSource + '''.' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple -------- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @TypeComposantInvalide = 'y' SET @ErreurDetectee = 'y' ---------- RETURN END ------------------------------------------ -- On s'assure que Cézigue a fourni -- une date pour le changement d'huile, -- sinon on perd du temps pour rien... ------------------------------------------ IF @OilChangeDate IS NULL BEGIN SET @Engueulade = @EngueuladeDebut + 'camion ''' + @CamionNumber + ''', composant de type ''' + @ComposantTypeSource + ''' : veuillez fournir la date de changement d''huile.' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple -------- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @OilChangeDateAbsente = 'y' SET @ErreurDetectee = 'y' -------------- RETURN END ------------------------------------------------- -- La suite des opérations nécessite d'avoir -- connaissance du type de composant ------------------------------------------------- IF @TypeComposantInvalide = 'n' BEGIN ------------------------------------------------------------------ -- Table locale @t servant à empiler pour un camion -- les identifiants des composants du type de composant -- fourni par Cézigue (moteur, transmission, axle positionné). -- En fait, cette table n'a d'intérêt que pour les transmissions, -- sachant que si Cézigue n'en fournit pas le numéro de série -- tandis qu'il y a plus d'une transmission pour le camion, -- alors on lui demandera de fournir ce numéro. Il s'agit d'un -- cas rare, mais pas impossible. -- Un camion n'ayant qu'un seul moteur, on sait le déterminer, -- il est donc inutile que Cézigue en fournisse le numéro de série. -- Quant aux axles, là encore il est inutile que Cézigue en -- fournisse le numéro de série, puisqu'on sait déterminer -- celui-ci en fonction de sa position sur le camion, -- position que Cézigue devra évidemment impérativement fournir. -- -- La table @t n'est pas essentielle : pour le camion et le -- type de composant en cours on pourrait se contenter d'un COUNT -- des composants, mais à l'avenir on pourrait être intéressé -- de savoir quels sont ces composants. ------------------------------------------------------------------ DECLARE @t TABLE ( ComposantId INT ) ------------------------------------------------- -- en cas d'insert multivalué, il faut -- virer ce qui a été empilé lors du tour -- de manège précédent. ------------------------------------------------- DELETE FROM @t ---------------------------------------------------- -- moteur ou transmission : empilement dans @t. -- -- Pour les axles, on attendra d'avoir traité -- de leur position sur le camion. ---------------------------------------------------- IF @ComposantType IN ('e', 't') BEGIN INSERT INTO @t SELECT DISTINCT x.ComposantId FROM COMPOSANT_AFFECTATION AS x JOIN COMPOSANT AS y ON x.ComposantId = y.ComposantId WHERE x.LocalisationId = @CamionId AND LOWER(y.ComposantType) = @ComposantType END ELSE -------------------------------------------- -- axles - contrôles liés à leur position -- et empilement dans @t. Cela suppose que -- le camion soit connu. -------------------------------------------- BEGIN IF @CamionNumberInvalide = 'n' BEGIN SET @PositionId = (SELECT PositionId FROM AXLE_POSITION WHERE PositionCode = @ComposantType) ---- pour debug ---- select @PositionId as '@PositionId' ----------------------------------------------------------- -- on vérifie qu'il y a bien un axle à la position proposée ----------------------------------------------------------- DECLARE @N2 AS INT SET @N2 = ( SELECT COUNT(*) FROM COMPOSANT_AFFECTATION AS x JOIN AXLE AS y ON x.ComposantId = y.ComposantId WHERE x.LocalisationId = @CamionId AND x.PositionId = @PositionId ) ---- pour debug ---- select @n2 as '@N2' IF @N2 = 0 BEGIN ------------------------------------------ -- Cézigue a fourni une position où il -- n'y a pas d'axle ------------------------------------------ SET @Engueulade = @EngueuladeDebut + 'Camion ''' + @CamionNumber + ''' : ' + 'Il n''y a pas d''axle en position ''' + @ComposantTypeSource + ''' (' + @ComposantType + ').' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple ---- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @AxlePositionInvalide = 'y' SET @ErreurDetectee = 'y' ------------ RETURN END --------------------------------------------------- -- Il y a bien un axle à la position proposée, -- on empile pour retrouver ensuite le traitement -- valant pour tous les types de composants. --------------------------------------------------- ELSE BEGIN INSERT INTO @t SELECT DISTINCT x.ComposantId FROM COMPOSANT_AFFECTATION AS x JOIN AXLE AS y ON x.ComposantId = y.ComposantId WHERE x.LocalisationId = @CamionId AND x.PositionId = @PositionId ---pour debug --- select '' as '@t !!', * from @t END END ------------------------------------------------------ -- terminé pour le contrôle de la position des axles ------------------------------------------------------ END -------------------------------------------------- -- -- Reprise des traitements communs à tous les -- types de cmposants -- -------------------------------------------------- ---- pour debug ---- select '' as '@t', * from @t ------------------------------------------------------ -- Rappel : à part le cas des transmissions (rare !), -- un composant n'a qu'un élément -- dans la pile des identifiants des composants. ------------------------------------------------------- ------------------------------------------------------- -- Normalement, Cézigue ne fournit pas le serial -- number d'un composant, mais s'il le fait, il faut -- s'assurer que c'est bien celui qui est connu -- dans la base de données. -- -- A noter que dans le cas des transmissions, -- s'il y en a plus d'une pour un camion, -- il faudra gueuler en demandant -- à Cézigue de fournir le numéro de série de la -- transmission à huiler. ------------------------------------------------------- --------------------------------------------------------- -- Comme la variable locale @ComposantId n'a le droit de -- prendre qu'une valeur, alors que pour une transmission -- on peut en avoir deux, on utilise l'astuce "TOP 1" -- afin de ne pas se faire massacrer par SQL Server, -- sachant qu'on traitera plus loin du cas de deux -- transmissions pour un camion. --------------------------------------------------------- SET @ComposantId = (SELECT TOP 1 ComposantId FROM @t) --- pour debug ---- select @ComposantId as '@ComposantId (TOP 1)' ----------------------------------------------------------------- -- Le numéro de série du composant qui est présent dans la base ----------------------------------------------------------------- SET @ComponentSerialNumberInDataBase = CASE @ComposantType WHEN 'e' THEN (SELECT MoteurNumeroSerie FROM MOTEUR WHERE ComposantId = @ComposantId) WHEN 't' THEN (SELECT TransmissionNumeroSerie FROM TRANSMISSION WHERE ComposantId = @ComposantId) ELSE (SELECT AxleSerialNumber FROM AXLE WHERE ComposantId = @ComposantId) END --- pour debug ---- select @ComponentSerialNumberInDataBase as '@ComponentSerialNumberInDataBase (TOP 1)' ------------------------------------------------------- -- S'il n'y a qu'un seul composant, tant mieux, -- c'est plus simple ! ------------------------------------------------------- SET @N = (SELECT COUNT(DISTINCT ComposantId) FROM @t) --- pour debug ---- select @N as '@N' IF @N = 1 BEGIN ------------------------------------------------------- -- On regarde si Cézigue a fourni un numéro de série. -- Dans la négative, c'est bien, et on prend celui -- qu'on a en base. S'il en a fourni un, on se doit -- de vérifier qu'il a fourni celui qu'on a en base. ------------------------------------------------------- IF @SerialNumber IS NULL OR LEN(TRIM(@SerialNumber)) > 0 BEGIN SET @SerialNumber = @ComponentSerialNumberInDataBase END ELSE BEGIN ---------------------------------------------------- -- Si Cézigue a proposé un numéro de série et que -- la base n'en contient qu'un pour le camion, -- d'accord, mais à condition que Cézigue soit -- en phase avec la base. ---------------------------------------------------- IF LOWER(@ComponentSerialNumberInDataBase) <> LOWER(@SerialNumber) BEGIN SET @Engueulade = @EngueuladeDebut + 'Camion ''' + @CamionNumber + ''', ' + @ComposantType + ' ; selon la base de données, le serial number correspondant n''est pas ''' + @SerialNumber + ''', mais ''' + @ComponentSerialNumberInDataBase + '''.' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple -------- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @SerialNumberInconnu = 'y' SET @ErreurDetectee = 'y' ----------- RETURN END END END -- fin de @N = 1 -------------------------------------------------------------- -- S'il y a plus d'un composant possible, cas des -- transmissions, pour que l'ambiguïté soit levée, Cézigue -- aura dû en fournir le numéro de série. -------------------------------------------------------------- IF @N > 1 BEGIN -------------------------------------------------------------- -- On a plus d'une occurrence de ComposantId dans la table @t : -- il s'agit de composants distincts (transmissions) -- Pour qu'il n'y ait pas d'ambiguïté, Cézigue aura dû fournir -- le numéro de série du composant en cours. S'il ne l'a pas -- fait, on l'engueule. -------------------------------------------------------------- IF @SerialNumber IS NULL BEGIN SET @Engueulade = @EngueuladeDebut + 'le camion ''' + @CamionNumber + ''' a ' + CAST(@N AS VARCHAR) + ' composants de type ' + @ComposantTypeSource + ', veuillez fournir le numéro de série de celui dont l''huile est changée.' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple -------- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @SerialNumberAbsent = 'y' SET @ErreurDetectee = 'y' ---------- RETURN END --------------------------------------------------------------- -- Cézigue a fourni un serial number, reste à vérifier qu'il -- existe dans la base. -- On recalcule @ComposantId, car celui obtenu initialement -- avec TOP 1 n'est pas forcément le bon et n'est pertinent -- que lorsqu'un camion n'a qu'une seul composant du type -- fourni par Cézigue. --------------------------------------------------------------- IF @SerialNumberAbsent = 'n' BEGIN SET @ComposantId = ( SELECT y.ComposantId FROM COMPOSANT_AFFECTATION AS x JOIN TRANSMISSION AS y ON x.ComposantId = y.ComposantId WHERE x.LocalisationId = @CamionId AND y.TransmissionNumeroSerie = @SerialNumber ) ---- pour debug ---- select @ComposantId as '@ComposantId (@N > 1)' ------------------------------------------------------- -- Si Cézigue a fourni un numéro de série inconnu, -- on dégage. ------------------------------------------------------- IF @ComposantId IS NULL BEGIN SET @Engueulade = @EngueuladeDebut + 'Camion ''' + @CamionNumber + ''', ' + @ComposantTypeSource + ' ; le serial number ''' + @SerialNumber + ''', n''est pas connu. ' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple ------ RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @SerialNumberInconnu = 'y' SET @ErreurDetectee = 'y' ---------- RETURN END END END -- fin de @N > 1 --- pour debug ---- select @ComposantId as '@ComposantId' ----------------------------------------------------- -- On s'assure que le composant n'a pas déjà -- fait l'objet d'un changement d'huile à la date -- fournie par Cézigue ----------------------------------------------------- DECLARE @Nchg as INT SET @Nchg = ( SELECT COUNT(*) FROM HUILE_CHANGEMENT WHERE ComposantId = @ComposantId AND HuileChangementDate = @OilChangeDate ) IF @Nchg > 0 BEGIN SET @Engueulade = @EngueuladeDebut + 'camion ''' + @CamionNumber + ''', ' + @ComposantTypeSource + ' ''' + @SerialNumber + ''' : changement d''huile déjà effectué le ' + CAST(@OilChangeDate AS VARCHAR) + ' (au besoin, faites un update).' SELECT @Engueulade AS Engueulons, @CurrentTuple AS CurrentTuple SET @Engueulade = @Engueulade + @CurrentTupleHeading + @CurrentTuple -------- RAISERROR (@Engueulade,16,1) -- state = 16 pour bloquer RAISERROR (@Engueulade,0,1) -- state = 0 pour les tests SET @ChangementDejaFait = 'y' SET @ErreurDetectee = 'y' ------------- RETURN END -- Fin du bloc @TypeComposantInvalide END ------------------------------------------------------------- -------------------------------------------------------------- -- Insert d'une ligne -------------------------------------------------------------- IF @ErreurDetectee = 'n' BEGIN ----pour debug --- select 'on tente l''insert' INSERT INTO HUILE_CHANGEMENT ( ComposantId , HuileChangementDate , HuileKm ) SELECT @ComposantId , COALESCE(@OilChangeDate, CAST('9999-12-31' as DATE)) , COALESCE(@OilChangeMilleage, 0) -- attention à la division par zéro... ; END -------------------------------------------- -- On entame le tour de manège suivant -- à cheval sur le curseur. -------------------------------------------- ---- pour debug --- select 'fetch suivant' FETCH theCurseur INTO @CamionVIN, @CamionNumber, @ComposantTypeSource, @SerialNumber, @OilChangeDate, @OilChangeMilleage -- LOOP -------------------------------------------- -- Fin du manège -------------------------------------------- END CLOSE theCurseur DEALLOCATE theCurseur END GO
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Bonjour fsmrel
J'avais penser à renommer la Colonne 'Transmission' en 'PrimaryTransmission' ajouter une Colonne 'AuxiliaryTransmission' et de les traiter indépendamment comme une autre entité comme on traite 'Moteur', 'Axle', 'Differential'. Donc l'usager pourrait installer la 'PrimaryTransmission' et si la Colonne 'AuxiliaryTransmission' est vide, on ne se casse pas la tête, le Camion n'en possède pas sauf évidemment si le Camion en possède une à l'origine et qu'elle est brisée et que l'utilisateur attend une remanufacturée pour la réinstaller dans le Camion. Il pourrait aussi simplement enlever la 'AuxiliaryTransmission' alors le Camion deviendrait comme les autres Camions avec seulement une Transmission.
Une Transmission Auxiliaire est comme un 'Transfert Case' sur un 4 X 4, vous savez avec un '4 X 4 Lo' et un '4 X 4 Hi'. Vous savez comme un tracteur de ferme avec 24 vitesses, il y a surement une transmission auxiliaire. Soit une transmission primaire avec 8 vitesses et une transmission auxiliaire avec 3 vitesses qui font un total de 24 vitesses ou une transmission primaire avec 6 vitesses et une transmission auxiliaire avec 4 vitesses qui font aussi un total de 24 vitesses. Je ne suis pas un spécialiste en tracteur de ferme mais je ne vois pas comment on pourrait entrer 24 vitesses dans une seule transmission... Pour les camions par contre, une transmission 18 vitesses, une 13 vitesses et une 9 vitesses sont des transmissions à peu près identiques en ce sens qu'une 13 vitesses est une 9 vitesses à laquelle on à ajouter une transmission auxiliaire à l'intérieur de celle-ci qui coupe de 50% le ratio entre les vitesses du palier supérieur qui donne ( Lo, 2, 3, 4, 5, 6Lo, 6Hi, 7Lo, 7Hi, 8Lo, 8Hi, 9Lo, 9Hi ) qui donnent 13 vitesses au total. Pour une transmission 18 vitesses c'est une transmission 9 vitesses avec une transmission auxiliaire interne qui coupe de 50% le ration du palier inférieur et du palier supérieur qui donne ( LoLo, Lo, 2Lo, 2Hi, 3Lo, 3Hi, 4Lo, 4Hi, 5Lo, 5Hi, 6Lo, 6Hi, 7Lo, 7Hi, 8Lo, 8Hi, 9Lo, 9Hi ) qui donne 18 vitesses au total. Lorsque qu'on a besoin de plus de rations, on rajoute une transmission auxiliaire extérieure qui recoupe de 50% tous les rations qui donnerait 26 vitesses ou 36 vitesses au total dépendamment de la transmission primaire. Facile les transmissions de camions n'est-ce pas ?
Pour revenir à nos colonnes, vous connaissez maintenant le principe de la transmission auxiliaire alors on y va avec la solution qui serait la meilleur pour vous, moi c'est le résultat qui compte… On y va pour la façon la plus facile pour développer le trigger....
Avez-vous visité le site WEB ? Ça fait beau pour les changements d'huile n'est-ce pas ? Comment trouvez-vous ma colonne ComponentType ?
Merci encore fsmrel pour votre aide et pour tout le temps que vous prenez à documenter vos Triggers, ça me permet de m'amuser et de mieux comprendre votre raisonnement derrière ces Triggers... J'espère qu'il y a des gens qui prennent la peine de visiter notre blog et d'étudier vos Triggers car c'est beaucoup plus facile à comprendre que dans les livres.
Pièce jointe 436989
Ouffff c'est tout un Trigger, je n'ai même pas eu le temps d'essayer votre deuxième version et vous arrivez déjà avec une troisième version.
Et comment l'utilisateur saura que la 3ième n'a pas passé ??? Si elle n'a pas passé, il faut revenir pour le forcer à corriger et réessayer de la faire passer. Si la 3ième ne passe pas, je serais plus restrictif, je n'en laisserais pas passer aucune avant qu'il ne corrige la 3ième. Je m'excuse si je n'ai pas compris, je n'ai pas encore eu le temps d'étudier votre Trigger....
Puisque j'étais seul à Noel, j'ai légèrement modifié la Table 'MAINTENANCE' que j'ai renommé 'TRUCK_MAINTENANCE_REPAIRS' et j'ai ajouté d'autres Tables en conséquence. Par contre je ne suis pas certain que ma solution est la meilleure et qu'elle est 100% fonctionnelle. Je n'ai pas encore tout vérifié. Désolé, c'est la version anglaise pour 'DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH' et ça ne fonctionnera pas dans 'DZINDZIO_TRUCKS_MANAGEMENT_TEMP' avant de retraduire en version mi-français/mi-anglais. Jetteriez-vous un petit coup d'oeil rapide pour voir si j'ai fait des erreurs ou si il y aurait une façon plus ergonomique de concevoir cette partie de la base de données ? Si vous acceptez cette version, je la retraduiré pour qu'elle fonctionne avec 'DZINDZIO_TRUCKS_MANAGEMENT_TEMP' Sinon, j'attendrai vos corrections. Pour l'instant ça donne joli mais sans les Triggers Inserts car je ne savais pas si vous accepteriez cette partie et si j'ai fait des erreurs… Je n'ai pas encore codé toutes les vues non plus car j'attendais vos suggestions.
Pièce jointe 437013
Pièce jointe 437009Pièce jointe 437012-------------------------------------------- ------------------------------------------ -----Table [dbo].[TRUCK_MILLEAGE] ------------------------------------------- ------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[TRUCK_MILLEAGE] Script Date: 2018-12-26 15:08:52 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[TRUCK_MILLEAGE] ( [TruckId] [int] NOT NULL, [TruckMilleageId] [int] IDENTITY(1,1) NOT NULL, [TruckMilleageDate] [date] NOT NULL, [TruckMilleage] [int] NOT NULL, CONSTRAINT [TRUCK_MILLEAGE_PK] PRIMARY KEY CLUSTERED ( [TruckId] ASC , [TruckMilleageId] ASC ) WITH (PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF , ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] , CONSTRAINT [TRUCK_MILLEAGE_AK] UNIQUE NONCLUSTERED ( [TruckId] ASC , [TruckMilleageDate] ASC ) WITH (PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[TRUCK_MILLEAGE] WITH CHECK ADD CONSTRAINT [FK_TRUCK_MILLEAGE_TRUCK] FOREIGN KEY([TruckId]) REFERENCES [dbo].[TRUCK] ([TruckId]) GO ALTER TABLE [dbo].[TRUCK_MILLEAGE] CHECK CONSTRAINT [FK_TRUCK_MILLEAGE_TRUCK] GO -------------------------------------------- ------------------------------------------ -----Table [dbo].[MAINTENANCE_REPAIRS] ------------------------------------------- ------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[MAINTENANCE_REPAIRS] Script Date: 2018-12-26 14:28:26 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[MAINTENANCE_REPAIRS] ( [TruckId] [int] NOT NULL, [TruckMilleageId] [int] NOT NULL, [MaintenanceRepairTypeId] [int] NOT NULL, [ShopId] [int] NOT NULL, [Details] [varchar](500) NOT NULL, [Note] [varchar](150) NOT NULL, [LaborPrice] [numeric](8, 2) NOT NULL, CONSTRAINT [PK_MAINTENANCE_REPAIRS_1] PRIMARY KEY CLUSTERED ( [TruckId] ASC , [TruckMilleageId] ASC, [MaintenanceRepairTypeId] ASC , [ShopId] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] ADD CONSTRAINT [DF_MAINTENANCE_REPAIRS_ShopId] DEFAULT ((1)) FOR [ShopId] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] ADD CONSTRAINT [DF_REPAIRS_Details] DEFAULT ('-') FOR [Details] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] ADD CONSTRAINT [DF_REPAIRS_Note] DEFAULT ('-') FOR [Note] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] ADD CONSTRAINT [DF_MAINTENANCE_REPAIRS_LaborsPrice] DEFAULT ((0)) FOR [LaborPrice] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] WITH CHECK ADD CONSTRAINT [FK_MAINTENANCE_REPAIRS_MAINTENANCE_REPAIRS_TYPE] FOREIGN KEY([MaintenanceRepairTypeId]) REFERENCES [dbo].[MAINTENANCE_REPAIRS_TYPE] ([MaintenanceRepairsTypeId]) GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] CHECK CONSTRAINT [FK_MAINTENANCE_REPAIRS_MAINTENANCE_REPAIRS_TYPE] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] WITH CHECK ADD CONSTRAINT [FK_MAINTENANCE_REPAIRS_SHOPS_LIST1] FOREIGN KEY([ShopId]) REFERENCES [dbo].[SHOPS_LIST] ([ShopId]) GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] CHECK CONSTRAINT [FK_MAINTENANCE_REPAIRS_SHOPS_LIST1] GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] WITH CHECK ADD CONSTRAINT [FK_MAINTENANCE_REPAIRS_TRUCK_MILLEAGE] FOREIGN KEY([TruckId], [TruckMilleageId]) REFERENCES [dbo].[TRUCK_MILLEAGE] ([TruckId], [TruckMilleageId]) GO ALTER TABLE [dbo].[MAINTENANCE_REPAIRS] CHECK CONSTRAINT [FK_MAINTENANCE_REPAIRS_TRUCK_MILLEAGE] GO ---------------------------------------------------------------------------- ----------------------------------------------------------------------------- -----Table [dbo].[MAINTENANCE_REPAIRS_TYPE] -------------------------------------------------------------------------- -------------------------------------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[MAINTENANCE_REPAIRS_TYPE] Script Date: 2018-12-26 14:32:21 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[MAINTENANCE_REPAIRS_TYPE] ( [MaintenanceRepairsTypeId] [int] IDENTITY(1,1) NOT NULL, [MaintenanceRepairsType] [nchar](32) NOT NULL, CONSTRAINT [MAINTENANCE_REPAIRS_TYPE_PK] PRIMARY KEY CLUSTERED ( [MaintenanceRepairsTypeId] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO -------------------------------------------------------- --------------------------------------------------------------- -----Table [dbo].[PARTS_CATEGORY_CATALOG] ---------------------------------------------------- ------------------------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[PARTS_CATEGORY_CATALOG] Script Date: 2018-12-26 14:34:16 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[PARTS_CATEGORY_CATALOG] ( [MaintenanceRepairTypeId] [int] NOT NULL, [PartsCatalogId] [int] NOT NULL, CONSTRAINT [PK_PARTS_CATEGORY_CATALOG] PRIMARY KEY CLUSTERED ( [MaintenanceRepairTypeId] ASC, [PartsCatalogId] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[PARTS_CATEGORY_CATALOG] WITH CHECK ADD CONSTRAINT [FK_PARTS_CATEGORY_CATALOG_MAINTENANCE_REPAIRS_TYPE1] FOREIGN KEY([MaintenanceRepairTypeId]) REFERENCES [dbo].[MAINTENANCE_REPAIRS_TYPE] ([MaintenanceRepairsTypeId]) GO ALTER TABLE [dbo].[PARTS_CATEGORY_CATALOG] CHECK CONSTRAINT [FK_PARTS_CATEGORY_CATALOG_MAINTENANCE_REPAIRS_TYPE1] GO ALTER TABLE [dbo].[PARTS_CATEGORY_CATALOG] WITH CHECK ADD CONSTRAINT [FK_PARTS_CATEGORY_CATALOG_PARTS_CATALOG] FOREIGN KEY([PartsCatalogId]) REFERENCES [dbo].[PARTS_CATALOG] ([PartsCatalogId]) GO ALTER TABLE [dbo].[PARTS_CATEGORY_CATALOG] CHECK CONSTRAINT [FK_PARTS_CATEGORY_CATALOG_PARTS_CATALOG] GO -------------------------------------------------------- --------------------------------------------------------------- -----Table [dbo].[PARTS_CATALOG] ---------------------------------------------------- ------------------------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[PARTS_CATALOG] Script Date: 2018-12-26 14:35:32 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[PARTS_CATALOG]( [PartsCatalogId] [int] IDENTITY(1,1) NOT NULL, [PartsSupplierId] [int] NOT NULL, [PartNumber] [varchar](25) NOT NULL, [PartName] [varchar](50) NOT NULL, [PartPrice] [numeric](8, 2) NOT NULL, [QuantityInventory] [int] NOT NULL, [PurchaseDate] [date] NOT NULL, CONSTRAINT [PK_PARTS_CATALOG_1] PRIMARY KEY CLUSTERED ( [PartsCatalogId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[PARTS_CATALOG] ADD CONSTRAINT [DF_PARTS_CATALOG_PartNumber] DEFAULT ('0') FOR [PartNumber] GO ALTER TABLE [dbo].[PARTS_CATALOG] ADD CONSTRAINT [DF_PARTS_CATALOG_PartPrice] DEFAULT ('0') FOR [PartPrice] GO ALTER TABLE [dbo].[PARTS_CATALOG] ADD CONSTRAINT [DF_PARTS_CATALOG_QuantityInventory] DEFAULT ((0)) FOR [QuantityInventory] GO ALTER TABLE [dbo].[PARTS_CATALOG] ADD CONSTRAINT [DF_PARTS_CATALOG_PurchaseDate] DEFAULT ('9999-12-31') FOR [PurchaseDate] GO ALTER TABLE [dbo].[PARTS_CATALOG] WITH CHECK ADD CONSTRAINT [FK_PARTS_CATALOG_PARTS_SUPPLIER] FOREIGN KEY([PartsSupplierId]) REFERENCES [dbo].[PARTS_SUPPLIER] ([PartsSupplierId]) GO ALTER TABLE [dbo].[PARTS_CATALOG] CHECK CONSTRAINT [FK_PARTS_CATALOG_PARTS_SUPPLIER] GO -------------------------------------------------------- --------------------------------------------------------------- -----Table [dbo].[PARTS_SUPPLIER] ---------------------------------------------------- ------------------------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[PARTS_SUPPLIER] Script Date: 2018-12-26 14:37:01 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[PARTS_SUPPLIER] ( [PartsSupplierId] [int] IDENTITY(1,1) NOT NULL, [PartSupplierName] [varchar](50) NOT NULL, [CivicNumber] [char](10) NOT NULL, [StreetName] [varchar](50) NOT NULL, [PartSupplierCity] [varchar](50) NOT NULL, [Province] [varchar](25) NOT NULL, [PostalCode] [char](10) NOT NULL, [PhoneNumber] [char](12) NOT NULL, [FaxNumber] [char](12) NOT NULL, CONSTRAINT [PARTS_SUPPLIER_PK] PRIMARY KEY CLUSTERED ( [PartsSupplierId] ASC ) WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_MAINTENANCE_REPAIRS_PARTS_PartPrice] DEFAULT ('-') FOR [CivicNumber] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_PARTS_SUPPLIER_StreetName] DEFAULT ('_') FOR [StreetName] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_PARTS_SUPPLIER_City] DEFAULT ('_') FOR [PartSupplierCity] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_PARTS_SUPPLIER_Province] DEFAULT ('_') FOR [Province] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_PARTS_SUPPLIER_PostalCode] DEFAULT ('--- ---') FOR [PostalCode] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_PARTS_SUPPLIER_PhoneNumber] DEFAULT ('000-000-0000') FOR [PhoneNumber] GO ALTER TABLE [dbo].[PARTS_SUPPLIER] ADD CONSTRAINT [DF_PARTS_SUPPLIER_FaxNumber] DEFAULT ('000-000-0000') FOR [FaxNumber] GO -------------------------------------------------------- --------------------------------------------------------------- -----Table [dbo].[SHOPS_LIST] ---------------------------------------------------- ------------------------------------------------------------- USE --[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: Table [dbo].[SHOPS_LIST] Script Date: 2018-12-26 14:38:00 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[SHOPS_LIST] ( [ShopId] [int] IDENTITY(1,1) NOT NULL, [ShopName] [varchar](50) NOT NULL, [CivicNumber] [char](10) NOT NULL, [StreetName] [varchar](50) NOT NULL, [ShopCity] [varchar](50) NOT NULL, [Province] [varchar](25) NOT NULL, [PostalCode] [char](10) NOT NULL, [PhoneNumber] [char](12) NOT NULL, [FaxNumber] [char](12) NOT NULL, [CellNumber] [char](12) NOT NULL, [OwnerLastName] [varchar](50) NOT NULL, [OwnerFirstName] [varchar](50) NOT NULL, CONSTRAINT [PK_SHOPS_LIST] PRIMARY KEY CLUSTERED ( [ShopId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_ShopName] DEFAULT ('-') FOR [ShopName] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_CivicNumber] DEFAULT ('-') FOR [CivicNumber] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_StreetName] DEFAULT ('-') FOR [StreetName] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_City] DEFAULT ('-') FOR [ShopCity] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPS_LIST_Province] DEFAULT ('-') FOR [Province] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_PostalCode] DEFAULT ('--- ---') FOR [PostalCode] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_PhoneNumber] DEFAULT ('000-000-0000') FOR [PhoneNumber] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_FaxNumber] DEFAULT ('000-000-0000') FOR [FaxNumber] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_CellNumber] DEFAULT ('000-000-0000') FOR [CellNumber] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_OwnerLastName] DEFAULT ('-') FOR [OwnerLastName] GO ALTER TABLE [dbo].[SHOPS_LIST] ADD CONSTRAINT [DF_SHOPSLIST_OwnerFirstName] DEFAULT ('-') FOR [OwnerFirstName] GO -------------------------------------------------------- --------------------------------------------------------------- -----VIEW [dbo].[TRUCK_MAINTENANCE_REPAIRS_V] ---------------------------------------------------- ------------------------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: View [dbo].[TRUCK_MAINTENANCE_REPAIRS_V] Script Date: 2018-12-26 14:39:43 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE VIEW [dbo].[TRUCK_MAINTENANCE_REPAIRS_V] AS SELECT r.TruckVIN AS [Truck VIN], r.TruckNumber AS [Truck Number], r.TruckRegistration AS [Plate Number] , s.TruckMilleageDate AS Date, s.TruckMilleage AS [Milleage(Km)] , u.MaintenanceRepairsType AS [Maintenance/Repairs Type] , t.Details, t.Note , x.PartName AS [Part Name], x.PartNumber AS [Part Number], x.PartPrice AS [Part Price] , y.PartSupplierName AS [Part Supplier] , w.ShopName AS [Shop Name], w.ShopCity AS [Shop City], w.PhoneNumber AS [Shop Phone Number] , t.LaborPrice AS [Labor Price] FROM dbo.PARTS_CATEGORY_CATALOG AS v INNER JOIN dbo.PARTS_CATALOG AS x INNER JOIN dbo.PARTS_SUPPLIER AS y ON x.PartsSupplierId = y.PartsSupplierId ON v.PartsCatalogId = x.PartsCatalogId INNER JOIN dbo.TRUCK AS r INNER JOIN dbo.TRUCK_MILLEAGE AS s ON r.TruckId = s.TruckId INNER JOIN dbo.MAINTENANCE_REPAIRS AS t ON s.TruckId = t.TruckId AND s.TruckMilleageId = t.TruckMilleageId INNER JOIN dbo.SHOPS_LIST AS w ON t.ShopId = w.ShopId INNER JOIN dbo.MAINTENANCE_REPAIRS_TYPE AS u ON t.MaintenanceRepairTypeId = u.MaintenanceRepairsTypeId ON v.MaintenanceRepairTypeId = u.MaintenanceRepairsTypeId GO -------------------------------------------------------- --------------------------------------------------------------- -----View [dbo].[SHOPS_LIST_V] ---------------------------------------------------- ------------------------------------------------------------- USE ---[DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO /****** Object: View [dbo].[SHOPS_LIST_V] Script Date: 2018-12-26 14:45:34 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE VIEW [dbo].[SHOPS_LIST_V] AS SELECT ShopName, CivicNumber, StreetName, ShopCity, Province, PostalCode, PhoneNumber , FaxNumber, CellNumber, OwnerLastName, OwnerFirstName FROM dbo.SHOPS_LIST GO
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Ça fait un moment que je n’ai pas visité le site... En tout cas les changements d’huile et la colonne ComponentType ça a de la gueule.
Je documente les triggers parce que ça me permet de vérifier que le code est correct, et il m’arrive encore de trouver des petits bugs, aussi je compte sur vous pour secouer le tout dernier.
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Par RAISERROR ou PRINT, je fournis un message correspondant à l’erreur. Le tuple en cause sera rejeté tant qu’il comportera une erreur.
Comme le deux premiers tuples ont été validés, ils sont partis dans la table, et pour les y supprimer, ou retarder leur insertion, c’est une (petite) usine à gaz en programmation, ou en gestion de COMMIT/ROLLBACK. Pour l’instant, j’ai pris le parti de réaliser les inserts pour tous les tuples validés et de rouspéter pour ceux qui ne le sont pas, en détaillant le motif de refus d’insert. Mais je regarderai comment ne déclencher les inserts en table qu’une fois tous les tuples du curseur valides, si vous préférez cette approche.
Comme je l’ai suggéré, voyez le dernier, tout en sachant qu’il sera revu du fait de ce que je viens d’écrire, et aussi à cause de la prise en compte des deux types de transmission.
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Bonjour fsmrel. Nous ne sommes vraiment plus synchro avec 'DZINDZIO_TRUCKS_MANAGEMENT_TEMP' alors ça devient un peu difficile à vous suivre pour les tests des Triggers. Puisque je vous ai donné le control total de 'DZINDZIO_TRUCKS_MANAGEMENT_TEMP' nous devons effacer les VUES désuètes et inutiles et renommer les VUES actives par leur vrai nom. Pour ne pas brouiller les cartes et faire certain que la mise à jour de vos Triggers fonctionnent toujours avec DZINDZIO_TRUCKS_MANAGEMENT_TEMP', je n'y fais plus de mise à jour. EX : Nous avons 'CAMION_HUILE_V' qui est inutile car incomplet. 'MOTEUR_HUILE_V' ne devait-elle pas être renommée 'CAMION_HUILE_V'???
SELECT * FROM CAMION_HUILE_V ;Quand est-il de 'CAMION_COMPOSITION_V' et de 'CAMION_COMPOSITION_V2' ???? Quelle est la version définitive ou désirez-vous conserver les deux ??? Devions-nous effacer 'CAMION_COMPOSITION_V' et renommer 'CAMION_COMPOSITION_V2' en 'CAMION_COMPOSITION_V' ???Msg 207, Level 16, State 1, Procedure CAMION_HUILE_V, Line 6 [Batch Start Line 0] Nom de colonne non valide*: 'HuileDateChangement'. Msg 207, Level 16, State 1, Procedure CAMION_HUILE_V, Line 6 [Batch Start Line 0] Nom de colonne non valide*: 'HuileDateChangement'. Msg 207, Level 16, State 1, Procedure CAMION_HUILE_V, Line 3 [Batch Start Line 0] Nom de colonne non valide*: 'HuileDateChangement'. Msg 4413, Level 16, State 1, Line 6 Impossible d'utiliser la vue ou la fonction 'CAMION_HUILE_V' à cause d'erreurs de liaison.
Bonsoir Ordigil,
Ça fait longtemps que je n’ai pas utilisé DZINDZIO_TRUCKS_MANAGEMENT_TEMP, ni Temp du reste.
Je vais tout virer de Temp et récréer tables, vues et triggers proprement, puis soumettre les jeux d’essai.
Pour le suivi au niveau du camion, on a en fait la vue CAMION_HUILE_SUIVI qui correspond à votre vue TRUCK_OIL_CHANGE_V. Quant à la vue MOTEUR_HUILE_V, sémantiquement parlant elle se situe au même plan que les vues AXLE_HUILE_V et TRANSMISSION_HUILE_V, elle ne concerne que les moteurs et doit donc conserver son nom. Il est un fait que, par erreur, elle est encore nommée CAMION_HUILE_V dans DZINDZIO_TRUCKS_MANAGEMENT_TEMP, suite à une distraction de ma part (confusion manifestement dyslexique entre les mots « camion » et « moteur »).
Pour la vue CAMION_COMPOSITION_V, elle a manifestement été remplacée par CAMION_COMPOSITION_V2 qui est moins bavarde, voyez le post #805. Je vais essayer de faire un peu le ménage de ce côté.
Bon, je passe à ma musique et ensuite je remets à plat la base Temp. Une fois celle-ci jugée satisfaisante, j’en fais autant pour DZINDZIO_TRUCKS_MANAGEMENT_TEMP, en espérant ne pas y ficher la zoubia...
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
onsoir Ordigil,
En passant :
A l’occasion de la remise à plat de ma base Temp, je constate que vous avez établi une clé étrangère pour la table MAINTENANCE_REPAIRS :
Où SHOPS_LIST est une variable de type TABLE :FOREIGN KEY (ShopId) REFERENCES SHOPS_LIST (ShopId)
Comment traduire « Shop » ? Par Magasin ? Atelier ? Autre ?CREATE TABLE SHOPS_LIST ( ShopId INT IDENTITY(1,1) NOT NULL, ShopName VARCHAR(50) NOT NULL, ... CONSTRAINT PK_SHOPS_LIST PRIMARY KEY (ShopId) )
Un « shop » est-il le lieu où s’effectue une maintenance, une réparation ? Si oui, s’agit-il d’un lieu dans votre entreprise ? Dans une autre entreprise pouvant effectuer des maintenances et des réparations concernant vos camions ?
L’attribut ShopId a intégré la clé primaire de la table MAINTENANCE_REPAIRS : cela signifie qu’une maintenance (ou une réparation) donnée peut être effectuée dans plusieurs shops en même temps : quel sens donner à cela ?
Concernant le nom des tables : une table est en réalité une variable de type TABLE et par respect de la logique des prédicats, un type est à nommer au singulier : MAINTENANCE_REPAIR et non pas MAINTENANCE_REPAIRS.
De même, si on peut avoir des listes de types, et si un type peut être du type LISTE, un type n’est pas une liste, en logique ça n’a pas de sens. Autrement dit, la variable SHOPS_LIST devrait être renommée tout simplement en SHOP.
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
J'ai apporté un très léger soupçon de modification dans le TRIGGER INSERT de la vue TRUCK_LOCALISATION_V
J'ai fait la même chose avec le Trigger UPDATE
Maintenant, si je fais ça :
USE [DZINDZIO_TRUCKS_MANAGEMENT_ENGLISH] GO INSERT INTO [dbo].[TRUCK_LOCALISATION_V] ([VIN] ,[Manufacturer] ,[Model] ,[WheelBase] ,[Color] ,[Number] ,[Registration]) VALUES ('nfhg783435irer' ,'maCk' ,'grAniTe' ,240 ,'orAnGE' ,'25467' ,'g5645 NB') GO SELECT * FROM TRUCK ; SELECT * FROM TRUCK_LOCALISATION_V ;
J'obtiens ça :
Pièce jointe 437229
Ça fait joli…
Bonsoir fsmrel
Oui Une shop c'est un garage, un atelier.
Oui nous avons notre propre garage et nous envoyons aussi nos camions dans d'autres garages. La même réparation dans plusieurs garages en même temps veut dire dans la même journée puisqu'on ne tient pas compte des heures dans notre base de données. Alors ça arrive que je fasse une réparation à notre garage et que le camion aille sur la route et qu'il revienne avec de nouveau le même problème alors nous l'envoyons chez le concessionnaire. L'inverse arrive aussi avec un camion qui a été réparé dans un autre garage et que je refais la même réparation dans notre propre garage la même journée.
Pour le nom des Tables, je vais corriger ;-)
D’accord pour les réparations, mais selon le modèle, un concessionnaire peut aussi effectuer des maintenances. Du point de vue du fonctionnel, est-ce possible ?Envoyé par ordigil
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Oui, le Concessionnaire et des garages indépendants font aussi des maintenances sur nos Camions car le Canada c'est très grand et lorsqu'un changement d'huile est dû, il faut qu'il soit fait. Alors des fois le camion est à 2000 Km de mon atelier alors la maintenance est effectuée où le camion est. À noter que les concessionnaires sont aussi mes fournisseurs de pièces pour les réparations de même que quelques magasins spécialisés dans les pièces de camions….
Par contre si vous voyez une meilleure solution pour la partie MAINTENANCE/RÉPARATIONS/PIÈCES/SHOPS, vous me le dites afin que la base de données demeure logique avec la façon que vous la développer et aussi qu'elle ne s'éloigne pas trop des standards établis …
D’accord.Envoyé par ordigil
A noter que si le garage G1 effectue une réparation de type T1 pour le camion C1 au kilométrage K1 (ou de façon équivalente à la date D1 puisque {CamionId, CamionMilleageId} et {CamionId, CamionMilleageDate} sont clés candidates de CAMION_MILLEAGE), le garage G2 pourra donc intervenir lui aussi pour cette réparation, mais G1 et G2 ne pourront intervenir chacun qu’une seule fois ce jour-là pour cette réparation.
Par ailleurs, ne serait-il pas utile de faire le distinguo entre réparation et maintenance ? Si oui, la mise en oeuvre pour la table MAINTENANCE_REPAIR d’une colonne du genre TypeIntervention prenant par exemple soit la valeur 'r' soit la valeur 'm' pourrait probablement suffire à cet effet.
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Donc, il serait préférable de corriger cette lacune car il pourrait très bien arriver comme dans le passée que je change un pneu sur un camion le matin et que le soir le même camion revient avec une crevaison à nouveau sur la même roue… Bon ça sera un autre pneu neuf mais ce sera quand même le même jour par contre il serait surprenant que ce soit le même Kilométrage…. Si avec KM le matin plus 1 KM je peux effectuer la même réparation, alors pas de problème, on peut ajouter 1 KM pour la réparation mais si ça ne passe pas à cause de la date, là il y aura un problème….
Oui, très bonne idée de spécifier si c'est une Réparation ou une Maintenance. Par contre j'ai une table que j'ai nommée MAINTENANCE_REPAIR_TYPE.... et dont une colonne s'affiche dans la vue TRUCK_MAINTENANCE_REPAIRS_V et qui se nomme Maintenance/Repair Type…. Peut-être faudrait-il renommer cette Table et aussi le nom de la colonne MaintenanceRepairType en autre chose… Cette table sert à spécifier quelle genre de réparation ou maintenance on effectue, donc la suspension, les freins, la direction, etc. qui correspondent exactement au manuel d'inspection mécanique du gouvernement… Si vous faites un SELECT * sur cette Table, vous comprendrez ce que je veux dire. Les éléments dans les colonnes ne changeront jamais car et il sera impossible pour l'utilisateur d'en rajouter ou dans retrancher afin de respecter le manuel du gouvernement...… Peut-être le nom le plus approprié pour cette table et pour la colonne serait MAINTENANCE_REPAIR_CATEGORY. Alors on pourrait utiliser votre suggestion pour spécifier si c'est une Réparation ou une Maintenance que nous avons effectuer dans cette Catégorie...
Code fsmrel : Sélectionner tout - Visualiser dans une fenêtre à part mais G1 et G2 ne pourront intervenir chacun qu’une seule fois ce jour-là pour cette réparation.
Il se fait tard, je reprends demain…
Buenas noches
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager