SQL Server BDD - E-Portfolio Christian COUDER
Transcription
SQL Server BDD - E-Portfolio Christian COUDER
BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII PROJET BASE DE DONNEES : SQL SERVER Présentation du projet : Le projet consiste à créer une base de données sous SQL SERVER pour pouvoir gérer un service hydrologique. Nous avons été chargés d’analyser les besoins de notre client « Mr Jean-François Boyer ». Pour cela nous avons fait une analyse à partir des informations relevées sur le document fourni par notre client ainsi que des informations notées en cours. Pour pouvoir répondre aux besoins du service hydrologique nous avons du comprendre ce qu’était le service hydrologique ? Le service hydrologique est donc composé de techniciens qui réalisent des mesures sur une rivière à une station donnée pour établir le débit à une date donnée. Les mesures prises par les techniciens avec la méthode du « jaugeage au moulinet » doivent donc être stockées et traitées dans une base de données. Objectif : L’objectif principal consiste à construire une base de données sous SQL Server pouvant stocker les informations nécessaires et calculer le résultat du débit d’un jaugeage effectué par le technicien hydrologue grâce à des procédures de la base de données qui généreront un rapport complet. BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII Règles de gestion : Voici les règles de gestion que nous avons trouvées par le biais de notre client : • • • • • • Un Technicien peut effectuer une ou plusieurs Mesures et une Mesure peut être effectuée que par un et un seul Technicien. Une Mesure est réalisée avec une seule Hélice et une Hélice peut réaliser une ou plusieurs mesures. Une Station appartient à une et une seul Rivière et une Rivière peut avoir plusieurs Stations. Une Mesure concerne une seule Station et une Station peut avoir une ou plusieurs Mesures. Une Mesure possède une ou plusieurs Verticales et une Verticale n’appartient qu’à une seule Mesure. Une Verticale a une ou plusieurs Horizontales et une Horizontale n’appartient qu’à une seule Verticale. Modèle Conceptuel des Données : BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii Modèle Physique des Données : Script pour créer la base de données : CREATE DATABASE HYDRO ON ( NAME = 'hydro_data', FILENAME = 'C:\hydro_data.MDF' , SIZE = 50, FILEGROWTH = 30%) LOG ON ( NAME = 'hydro_log', FILENAME = 'C:\hydro_log.LDF' , SIZE = 10, FILEGROWTH = 20%) EPSI CSII BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii Script des tables avec clés primaires : create table HORIZONTALE ( NUMHORIZONTALE int not null , NUMVERTICALE int not null , NBTOURS real null , PROFONDEUR real null , TEMPS real null , VITESSE real null , constraint PK_HORIZONTALE primary key (NUMHORIZONTALE) ) create table STATION ( CODESTATION char(32) not null , NUMRIVIERE int not null , NOMSTATION char(32) null , LONGITUDE real null , LATITUDE real null , constraint PK_STATION primary key (CODESTATION) ) create table TECHNICIEN ( NUMSECU int not null , NOM char(32) null , PRENOM char(32) null , ADRESSE char(100) null , DATEEMB datetime null , SALAIRE real null , constraint PK_TECHNICIEN primary key (NUMSECU) ) create table VERTICALE ( NUMVERTICALE int not null , CODEMESURE int not null , ABSCISSE int null , PU real null , constraint PK_VERTICALE primary key (NUMVERTICALE) ) EPSI CSII BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii create table HELICE ( CODEHELICE char(10) not null , PAS real null , MARQUE char(32) null , A1 real null , B1 real null , LIMITE1 real null , A2 real null , B2 real null , LIMITE2 real null , A3 real null , B3 real null , constraint PK_HELICE primary key (CODEHELICE) ) create table MESURE ( CODEMESURE int not null , CODEHELICE char(10) not null , CODESTATION char(32) not null , NUMSECU int not null , DATEMESURE datetime null , DEBIT real null , HAUTEUR real null , LARGEUR real null , CONSTFOND real null , constraint PK_MESURE primary key (CODEMESURE) ) create table RIVIERE ( NUMRIVIERE int not null , NOMRIVIERE char(32) null , constraint PK_RIVIERE primary key (NUMRIVIERE) ) EPSI CSII BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII Références sur les tables : On ajoute les contraintes de clés étrangères sur les tables : alter table HORIZONTALE add constraint FK_HORIZONTALE_VERTICALE foreign key (NUMVERTICALE) references VERTICALE (NUMVERTICALE) alter table STATION add constraint FK_STATION_RIVIERE foreign key (NUMRIVIERE) references RIVIERE (NUMRIVIERE) alter table MESURE add constraint FK_MESURE_HELICE foreign key (CODEHELICE) references HELICE (CODEHELICE) alter table MESURE add constraint FK_MESURE_STATION foreign key (CODESTATION) references STATION (CODESTATION) alter table MESURE add constraint FK_MESURE_TECHNICIEN foreign key (NUMSECU) references TECHNICIEN (NUMSECU) alter table VERTICALE add constraint FK_VERTICALE_MESURE foreign key (CODEMESURE) references MESURE (CODEMESURE) Les Index : Un index est une fonctionnalité permettant d'effectuer des accès rapides aux enregistrements d'une table. Si nos techniciens hydrologues effectuent d’avantage de requêtes sur le nom des stations et des rivières alors il vaut mieux faire un index sur le nom. create index I_NOM_RIVIERE on RIVIERE (NOMRIVIERE) create index I_NOM_TECHNICIEN on TECHNICIEN (NOM) create index I_NOM_STATION on STATION (NOMSTATION) BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii Création des contraintes de domaine a) Valeurs par défaut ALTER TABLE HORIZONTALE ADD CONSTRAINT VD_Nbtours DEFAULT (0) FOR NbTours ALTER TABLE HORIZONTALE ADD CONSTRAINT VD_temps DEFAULT (1) FOR temps * Nous avons mis le temps à 1 par défaut pour éviter des erreurs de calculs b) Domaine de valeurs Alter table HORIZONTALE add Constraint DV_temps check (temps > 0) Alter table HORIZONTALE add Constraint DV_profondeur check (profondeur >= 0) Alter table TECHNICIEN add Constraint DV_date_emb check (dateemb < getdate() ) Alter table TECHNICIEN add Constraint DV_Salaire check (salaire > 1254 ) Alter table MESURE add Constraint DV_date_mesure check (datemesure <= getdate() ) Alter table STATION add Constraint DV_latitude check (latitude >= -90 and latitude <= 90) Alter table STATION add Constraint DV_longitude check (longitude >= -180 and longitude <= 180) EPSI CSII BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII Règles de gestions pour calculer le débit d’une mesure Pour pouvoir calculer le débit d’une mesure : • Il faut d’abord calculer la vitesse d’une horizontale (Point de mesure finalement) qui se calcule à l’aide de la fonction : V=A*T+B A est le pas de l’hélice en mètre, T le nombre de tours d’hélice par seconde, et B la vitesse de frottement ou vitesse de démarrage. T est la variable mesurée sur la rivière par le technicien hydrologue, lorsque le moulinet est immergé. A et B sont des variables qui dépendent de l’hélice et des valeurs limites L1 et L2. Ce sont des données de constructeurs. • Ensuite il faut calculer les PU de chaque verticale : Chaque verticale inclut une ou plusieurs Horizontales, et à chaque Horizontale correspond à une vitesse. Donc on va utiliser la méthode des trapèzes pour pouvoir calculer les aires de chaque PU avec la formule : Aire = distance (Vitesse1 + Vitesse2) / 2 La distance est la différence de profondeur entre 2 horizontales. La vitesse 1 et 2 correspondent à une vitesse1 d’une horizontale1 et à une vitesse 2 d’une horizontale 2 qui sont dites « côte à côte ». Sauf pour la première et la seconde horizontale où on admettra 0 en PU et pour la dernière horizontale qui aura une profondeur égale à 0, on garde la même PU que la précédente. Le cumul de toutes ces aires permettra d’avoir le PU d’une verticale. • Enfin pour calculer le débit on utilise la même méthode des trapèzes avec toutes les verticales d’une même mesure : Aire = distance*(pu1+pu2)/2 La distance est la différence d’abscisse entre 2 verticales. La PU 1 et 2 correspondent à une PU1 d’une verticale1 et à une PU 2 d’une verticale 2 qui sont dites « côte à côte ». Il faudrait prendre en compte aussi dans ce cas là, l’abscisse au point 0 à la première verticale mais aussi la dernière abscisse à la fin de la rivière (largueur total de la rivière). Le cumul de toutes ces aires permettra d’avoir le débit d’une mesure. BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII Les Procédure stockées : Elles permettent de calculer la vitesse d’une horizontale, le PU d’une verticale, le débit d’une mesure et de générer un rapport complet. a) Vitesse d’une horizontale ( ou Point de mesure ) CREATE PROC CalculVitesse @NumHorizontale int, @NbTours real=0, @CodeHelice char(10)='', @NumVerticale int = 0, @vitesse real=0, @profondeur int=0 /*Déclaration de variables*/ AS /*On retrouve le @numVerticale à partir de l'horizontale */ SET @NumVerticale=(SELECT NUMVERTICALE FROM HORIZONTALE WHERE NUMHORIZONTALE = @NumHorizontale ) /*On retrouve le @codehelice à partir de l'horizontale*/ SET @CodeHelice =(SELECT HELICE.CODEHELICE FROM HELICE,MESURE,HORIZONTALE,VERTICALE WHERE HELICE.CODEHELICE =MESURE.CODEHELICE AND MESURE.CODEMESURE = VERTICALE.CODEMESURE AND HORIZONTALE.NUMVERTICALE = VERTICALE.NUMVERTICALE AND NUMHORIZONTALE = @NumHorizontale ) /*On retrouve le nombre de tours ( divisé par le temps ) à partir de l'horizontale*/ SET @NbTours=(SELECT Nbtours / Temps FROM HORIZONTALE WHERE NUMHORIZONTALE = @NumHorizontale) IF((SELECT COUNT(*) FROM HORIZONTALE WHERE NUMVERTICALE=@NumVerticale)=1) /*On compare le nombre d'horizontale à 1 Si il est égal alors on met la premiere vitesse à 0 */ BEGIN SET @vitesse=0 END ELSE BEGIN BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII SET @profondeur = ( SELECT profondeur FROM HORIZONTALE WHERE NUMHORIZONTALE = @NumHorizontale ) /*On affecte @profondeur à partir de l'horizontale */ IF (@profondeur=0 ) /*Cas particulier si la profondeur est égale à zéro on prend la derniere vitesse */ BEGIN SET @profondeur = ( SELECT MIN(profondeur) FROM HORIZONTALE WHERE NUMVERTICALE = @NumVerticale and profondeur != 0 ) SET @vitesse = (SELECT vitesse FROM HORIZONTALE WHERE profondeur = @profondeur and NUMVERTICALE = @NumVerticale ) END ELSE /*Sinon on regarde les caractéristiques de l'hélice pour pouvoir calculer la vitesse*/ BEGIN IF(SELECT Limite1 FROM HELICE WHERE CODEHELICE=@CodeHelice) > @NbTours /*Si la limite 1 est supérieur à nombre de tours alors */ BEGIN SET @vitesse=((SELECT A1 FROM HELICE WHERE CODEHELICE=@CodeHelice)*@NbTours+(SELECT B1 FROM HELICE WHERE CODEHELICE=@CodeHelice)) /*on affecte la vitesse selon A1 et B1 */ END ELSE BEGIN IF(SELECT Limite2 FROM HELICE WHERE CODEHELICE=@CodeHelice) > @NbTours /*On fait pareil pour savoir si le nombre de tours est supérieur à limite 2 */ BEGIN SET @vitesse = (( SELECT A2 FROM HELICE WHERE CODEHELICE=@CodeHelice)*@NbTours+(SELECT B2 FROM HELICE WHERE CODEHELICE=@CodeHelice)) /*on affecte la vitesse selon A2 et B2 */ END ELSE BEGIN /*sinon on affecte la vitesse selon A3 et B3 */ SET @vitesse=((SELECT A3 FROM HELICE WHERE CODEHELICE=@CodeHelice)*@NbTours+(SELECT B3 FROM HELICE WHERE CODEHELICE=@CodeHelice)) END END END END UPDATE HORIZONTALE /*Mise à jour dans la table horizontale de la vitesse*/ SET VITESSE=@vitesse WHERE NUMHORIZONTALE = @NumHorizontale GO BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII b) Calcul du PU d’une verticale CREATE PROC calculPu @NumVerticale int, @profondeur1 real=0, @profondeur2 real=0, @distance real =0, @compteur int=0, @v1 real=0, @v2 real=0, @aire real=0 AS SET @compteur =( SELECT count(*) FROM HORIZONTALE WHERE NumVerticale = @NumVerticale ) /* Nombres d'horizontales dans un compteur */ WHILE @compteur > 1 /* tant qu'on a des horizontales on traite */ BEGIN IF ( @profondeur1 = 0 ) /* Cas pour la première horizontale */ BEGIN SET @profondeur1 = ( SELECT MAX(profondeur) from HORIZONTALE WHERE NumVerticale = @NumVerticale ) SET @profondeur2 = ( SELECT MAX(profondeur) from HORIZONTALE WHERE NumVerticale = @NumVerticale and profondeur < @profondeur1 ) END ELSE /* pour toutes les horizontales :*/ BEGIN SET @profondeur1 = @profondeur2 SET @profondeur2 = ( SELECT MAX(profondeur) from HORIZONTALE WHERE NumVerticale = @NumVerticale and profondeur < @profondeur1 ) END SET @v1 = ( SELECT vitesse from HORIZONTALE where NumVerticale = @NumVerticale and profondeur = @profondeur1 ) SET @v2 = ( SELECT vitesse from HORIZONTALE where NumVerticale = @NumVerticale and profondeur = @profondeur2 ) SET @distance = @profondeur1 - @profondeur2 /* La différence de profondeur */ SET @aire=@aire+@distance*(@v1+@v2)/2 /* Cumul des aires */ SET @compteur = @compteur - 1 /* décrémente le compteur */ END BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII UPDATE VERTICALE SET PU=@aire / 100 /* Car c'est des cms ! dont on divise par 100 pour trouver des metres */ WHERE NumVerticale = @NumVerticale GO c) Calcul d’un débit : CREATE PROC calculDebit @CodeMesure int, @ab1 real=0, /*Déclaration de variables */ @ab2 real=0, @distance real =0, @compteur int=0, @compteurdepart int=0, @pu1 real=0, @pu2 real=0, @aire real=0, @larg real=0 AS SET @compteur =( SELECT count(*) FROM VERTICALE WHERE CodeMesure = @CodeMesure ) /*Un Compteur de verticales*/ SET @compteurdepart = @compteur WHILE @compteur > 1 /* Tant qu'on a des verticales à traiter on fait ce qui suit*/ BEGIN IF ( @compteur = @compteurdepart ) /*Si c'est la première verticale*/ BEGIN SET @ab1 = ( SELECT MAX(abscisse) from VERTICALE WHERE CodeMesure = @CodeMesure ) SET @ab2 = ( SELECT MAX(abscisse) from VERTICALE WHERE CodeMesure = @CodeMesure and abscisse < @ab1 ) END ELSE /*Sinon on Choisit les prochaines verticales*/ BEGIN SET @ab1 = @ab2 SET @ab2 = ( SELECT MAX(abscisse) from VERTICALE WHERE CodeMesure = @CodeMesure and abscisse < @ab1 ) END SET @pu1 = ( SELECT PU from VERTICALE where CodeMesure = @CodeMesure and abscisse = @ab1 ) /*Recupère le PU1*/ SET @pu2 = ( SELECT PU from VERTICALE where CodeMesure = @CodeMesure and abscisse = @ab2 ) /*Recupère le PU2 */ SET @distance = @ab1 - @ab2 BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii SET @aire=@aire+@distance*(@pu1+@pu2)/2 EPSI CSII /*Calcule des aires du trapèze*/ SET @compteur = @compteur - 1 END /* Plus on ajoute l'aire qui commence de 0 et va jusqu'à l'abcisse 1 */ SET @ab1 = ( SELECT MIN(abscisse) from VERTICALE WHERE CodeMesure = @CodeMesure ) SET @pu1 = ( SELECT PU from VERTICALE where CodeMesure = @CodeMesure and abscisse = @ab1 ) SET @aire=@aire+(@ab1*@pu1)/2 /* Plus on ajoute l'aire qui va de l'avant derniere abcisse à la derniere abcisse */ SET @larg= ( SELECT largeur FROM MESURE WHERE CodeMesure = @CodeMesure ) SET @ab2 = ( SELECT MAX(abscisse) from VERTICALE WHERE CodeMesure = @CodeMesure ) SET @pu2 = ( SELECT PU from VERTICALE where CodeMesure = @CodeMesure and abscisse = @ab2 ) SET @larg = @larg - @ab2 SET @aire=@aire+(@larg*@pu2)/2 UPDATE MESURE /*Mise à jour du débit dans la table mesure*/ SET Debit=@aire WHERE CodeMesure = @CodeMesure GO c) Rapport d’une mesure : CREATE PROC Rapport @CodeMesure int, @Hauteur real=0, @Debit real=0, /*Déclaration de variables */ @Station int=0, @DateMesure datetime='1/1/1', @CodeHelice int=0, @PasHelice real=0, @ConstFond real=0, @Largeur real=0, @NumVerticale int=0, @NumHorizontale int=0 , @Profondeur real=0, @abs int=0, @PU real=0, @nbtours real=0, BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII @Temps real=0, @Vitesse real=0 AS PRINT '******************* Hydrometrie **********************' PRINT ' DEPOUILLEMENT DU JAUGEAGE ' PRINT' ' PRINT' ' SET @Station=(SELECT CodeStation FROM MESURE WHERE CodeMesure = @CodeMesure ) /*On fait des requetes pour chaque attribut du rapport */ PRINT ' Station : ' + CAST(@Station AS VARCHAR(10)) SET @Hauteur=(SELECT Hauteur FROM MESURE WHERE CodeMesure = @CodeMesure ) PRINT ' Hauteur : ' + CAST(@Hauteur AS VARCHAR(10)) + ' cm' SET @Largeur=(SELECT Largeur FROM MESURE WHERE CodeMesure = @CodeMesure ) PRINT ' Largeur : ' + CAST(@Largeur AS VARCHAR(10)) + ' cm' SET @Debit=(SELECT Debit FROM MESURE WHERE CodeMesure = @CodeMesure ) PRINT ' Debit : ' + CAST(@Debit AS VARCHAR(10)) + ' M3/S' PRINT ' Jaugeage : ' + CAST(@CodeMesure AS VARCHAR(10)) SET @DateMesure =(SELECT DateMesure FROM MESURE WHERE CodeMesure = @CodeMesure ) PRINT ' Date : ' + CAST(@DateMesure AS VARCHAR(12)) SET @CodeHelice =(SELECT CodeHelice FROM MESURE WHERE CodeMesure = @CodeMesure ) PRINT ' Helice : ' + CAST(@CodeHelice AS VARCHAR(12)) SET @PasHelice =(SELECT Pas FROM MESURE,HELICE WHERE MESURE.CodeHelice = Helice.CodeHelice and CodeMesure = @CodeMesure ) PRINT ' Pas : ' + CAST(@PasHelice AS VARCHAR(12)) SET @ConstFond =(SELECT ConstFond FROM MESURE WHERE CodeMesure = @CodeMesure ) PRINT ' CSTE FOND : ' + CAST(@ConstFond AS VARCHAR(12)) PRINT '' PRINT '' PRINT ' RESULTAT PAR VERTICALE ' BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII DECLARE VERT CURSOR FOR /*On créer un curseur qui permettra de sortir à l'écran toutes les verticales */ SELECT NumVerticale,abscisse,PU FROM Verticale WHERE CodeMesure = @CodeMesure OPEN VERT FETCH NEXT FROM VERT INTO @NumVerticale,@abs,@PU WHILE @@FETCH_STATUS = 0 BEGIN PRINT ' VERT no ABSC.(m) P.U.(m²/s)' PRINT CAST(@NumVerticale AS VARCHAR(12)) + ' VARCHAR(12))+ ' ' + CAST(@PU AS VARCHAR(12)) FETCH NEXT FROM VERT INTO @NumVerticale,@abs,@PU ' + CAST(@abs AS END CLOSE VERT DEALLOCATE VERT PRINT '' PRINT '' DECLARE VERT CURSOR FOR /*On déclare un cuseur dans un curseur pour pouvoir trier les horizontales par verticales ! d'où l'utilité de 2 curseurs */ SELECT NumVerticale FROM Verticale WHERE CodeMesure = @CodeMesure OPEN VERT FETCH NEXT FROM VERT INTO @NumVerticale WHILE @@FETCH_STATUS = 0 BEGIN PRINT ' *************** VERT no ' + CAST(@NumVerticale AS VARCHAR(12)) + ' ******************* ' /* par Horizontale */ DECLARE HORI CURSOR FOR SELECT profondeur,nbtours,temps,vitesse FROM horizontale WHERE NumVerticale=@NumVerticale ORDER by 1 desc BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII OPEN HORI FETCH NEXT FROM HORI INTO @Profondeur,@nbtours,@temps,@vitesse WHILE @@FETCH_STATUS = 0 BEGIN PRINT ' Profondeur(cm) Nbre Tours Temps Vitesse(m/s)' PRINT CAST(@Profondeur AS VARCHAR(12)) + ' ' + CAST(@nbtours AS VARCHAR(12)) + ' ' + CAST(@temps AS VARCHAR(12))+ ' '+ CAST(@vitesse AS VARCHAR(12)) FETCH NEXT FROM HORI INTO @Profondeur,@Nbtours,@temps,@vitesse END CLOSE HORI DEALLOCATE HORI FETCH NEXT FROM VERT INTO @NumVerticale END CLOSE VERT DEALLOCATE VERT GO BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii Extrait du rapport sous SQL server EPSI CSII BDD - COUDER Christian – KENNES Thierry - LONGINE Heiarii EPSI CSII Les Vues : Nous avons pris l’initiative que le salaire des salariés serait caché pour permettre à certaines personnes de ne pas pouvoir voir le salaire des techniciens. Pour cela nous avons créé une vue sur la table technicien sans le salaire : CREATE VIEW TECHNICIEN_SANS_SALAIRE AS SELECT NUMSECU, NOM, PRENOM, ADRESSE, DATEEMB FROM TECHNICIEN Les Triggers : Ce trigger permet lorsqu’on insère une nouvelle horizontale, le calcul direct du débit car on execute directement les 3 procédures qui sont CalculVitesse, CalculPu et CalculDébit. CREATE TRIGGER T1 ON HORIZONTALE AFTER INSERT AS BEGIN DECLARE @NumHorizontale int, @NumVerticale int, @CodeMesure int SET @NumHorizontale=(SELECT NumHorizontale from inserted) SET @NumVerticale = (SELECT NumVerticale from HORIZONTALE where NumHorizontale = @NumHorizontale) SET @CodeMesure = ( SELECT CodeMesure from VERTICALE where NumVerticale = @NumVerticale ) exec CalculVitesse @NumHorizontale exec CalculPu @NumVerticale exec CalculDebit @CodeMesure END