You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

-- ! Tracer les suppressions.
-- ? Q1). Que fait la commande suivante ?
SELECT current_role , current_catalog;
-- Elle recupere et affiche le Role actuel (la personne qui est sur cette base de donnée) et la base de donnée actuel
-- ? Q2). Créer la table Log(quand, qui, quoi) où quand est un timestamp, qui est une chaîne de 20 caractères et quoi est une chaîne dau plus 800 caractères.
DROP TABLE IF EXISTS Log CASCADE;
CREATE TABLE Log (
quand timestamp,
qui char(20),
quoi varchar(800)
);
-- ? Q3 ). Ajouter les faux joueurs suivants :
-- ? 1001, Todd Jackson, USA
-- ? 1002, Michael Matthews, USA
-- ? 1003, Jamie Griffith, USA
-- ? 1004, Iloy Roberts, Belgium
-- ? 1005, Erin Kolthof, Belgium
INSERT INTO Player VALUES(1001, 'Todd Jackson', 'USA');
INSERT INTO Player VALUES(1002, 'Michael Matthews', 'USA');
INSERT INTO Player VALUES(1003, 'Jamie Griffith', 'USA');
INSERT INTO Player VALUES(1004, 'Iloy Roberts', 'Belgium');
INSERT INTO Player VALUES(1005, 'Erin Kolthof', 'Belgium');
-- ? Q4 ). Créer un trigger qui permette de tracer dans la table Log la suppression dun joueur afin
-- ? de connaître lutilisateur qui a réalisé la suppression, quand la suppression a été réalisée et quelles informations ont été supprimées.
-- DROP FUNCTION trig_trace_delete CASCADE;
-- CREATE OR REPLACE FUNCTION trig_trace_delete() RETURNS trigger AS $$
-- BEGIN
-- INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'suppression de l''id :' || OLD.id || ', avec le nom : ' || OLD.name);
-- RETURN OLD;
-- END;
-- $$ LANGUAGE plpgsql;
-- CREATE OR REPLACE trigger tracerLog BEFORE DELETE ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_delete();
-- ? Q5). Supprimer le joueur Michael Matthews, puis tous les joueurs belges et vérifier que votre trigger fonctionne.
DELETE FROM Player WHERE name = 'Michael Matthews';
DELETE FROM Player WHERE country = 'Belgium';
SELECT * FROM Log;
-- quand | qui | quoi
-- ----------------------------+----------------------+-----------------------------------------------------------
-- 2023-12-06 08:43:58.474339 | Perederii | suppression de l'id :1002, avec le nom : Michael Matthews
-- 2023-12-06 08:44:49.91823 | Perederii | suppression de l'id :1004, avec le nom : Iloy Roberts
-- 2023-12-06 08:44:49.91823 | Perederii | suppression de l'id :1005, avec le nom : Erin Kolthof
-- (3 rows)
-- ? Q6). Nous voulons désormais tracer tous les changements fait dans la table Player (ajout, suppres- sion et modification de ligne). Comme précédemment, toutes les informations concernant ces change- ments sont stockées dans la table Log.
-- ? Proposez deux façons différentes permettant de stocker un message différent dans la colonne quoi en fonction du type de changement réalisé.
-- ! Premiere maniere :
-- DROP FUNCTION trig_trace_delete CASCADE;
-- DROP FUNCTION trig_trace_insert CASCADE;
-- DROP FUNCTION trig_trace_update CASCADE;
-- CREATE OR REPLACE FUNCTION trig_trace_delete() RETURNS trigger AS $$
-- BEGIN
-- INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'suppression de l''id :' || OLD.id || ', avec le nom : ' || OLD.name || ' et le pays : ' || OLD.country);
-- RETURN OLD;
-- END;
-- $$ LANGUAGE plpgsql;
-- CREATE OR REPLACE trigger tracerLogDelete BEFORE DELETE ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_delete();
-- CREATE OR REPLACE FUNCTION trig_trace_update() RETURNS trigger AS $$
-- BEGIN
-- INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'update de l''id :' || OLD.id || ', en : ' || NEW.id || ', avec le nom : ' || OLD.name
-- || ', en : ' || NEW.name || ' et le pays : ' || OLD.country || ', en ' || NEW.country);
-- RETURN NEW;
-- END;
-- $$ LANGUAGE plpgsql;
-- CREATE OR REPLACE trigger tracerLogUpdate AFTER UPDATE ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_update();
-- CREATE OR REPLACE FUNCTION trig_trace_insert() RETURNS trigger AS $$
-- BEGIN
-- INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'insert de l''id :' || NEW.id || ', avec le nom : ' || NEW.name || ' et le pays : ' || NEW.country);
-- RETURN NEW;
-- END;
-- $$ LANGUAGE plpgsql;
-- CREATE OR REPLACE trigger tracerLogInsert BEFORE INSERT ON Player
-- FOR EACH ROW
-- EXECUTE FUNCTION trig_trace_insert();
-- ! Deuxieme maniere :
CREATE OR REPLACE FUNCTION trig_trace() RETURNS trigger AS $$
BEGIN
IF TG_OP = 'DELETE' THEN
INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'suppression de l''id :' || OLD.id || ', avec le nom : ' || OLD.name || ' et le pays : ' || OLD.country);
RETURN OLD;
ELSIF TG_OP = 'INSERT' THEN
INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'insert de l''id :' || NEW.id || ', avec le nom : ' || NEW.name || ' et le pays : ' || NEW.country);
RETURN NEW;
ELSE
INSERT INTO Log VALUES(CURRENT_TIMESTAMP, (SELECT current_role), 'update de l''id :' || OLD.id || ', en : ' || NEW.id || ', avec le nom : ' || OLD.name
|| ', en : ' || NEW.name || ' et le pays : ' || OLD.country || ', en ' || NEW.country);
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE trigger tracerLogAll BEFORE INSERT OR UPDATE OR DELETE ON Player
FOR EACH ROW
EXECUTE FUNCTION trig_trace();
-- ? Q7). Vérifier que cela fonctionne.
-- C'est OK
-- ! Meilleur marqueur.
-- ? Q8). Créer la table BestScorer qui contient le maximum de points marqués par un joueur lors dun match, lid du joueur ayant réalisé ce record et lid du match.
-- DROP TABLE BestScorer;
-- CREATE TABLE BestScorer(
-- maxPts numeric,
-- idPlayer varchar(10),
-- idGame char(8)
-- );
-- ? Q9). Créer un trigger permettant de mettre à jour cette table lors de linsertion de nouveaux résultats de match.
-- INSERT INTO BestScorer(maxPts, idPlayer, idGame) SELECT DISTINCT gd.points, gd.idPlayer, gd.idGame
-- FROM GameDetail gd
-- WHERE gd.points >= ALL(SELECT points FROM GameDetail WHERE idGame = gd.idGame);
CREATE OR REPLACE FUNCTION fctMatch() RETURNS trigger AS $$
BEGIN
-- ! Verifie si dans BestScorer si pas, on, insert, si >, on insert sinon on fait rien
IF (SELECT count(*) FROM BestScorer WHERE idGame = NEW.idGame) = 0 THEN
INSERT INTO BestScorer VALUES(NEW.points, NEW.idPlayer, NEW.idGame);
ELSEIF NEW.points > (SELECT DISTINCT maxPts FROM BestScorer WHERE idGame = NEW.idGame) THEN
UPDATE BestScorer SET maxPts = NEW.points, idPlayer = NEW.idPlayer WHERE idGame = NEW.idGame;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE trigger trigTraceMatch BEFORE INSERT ON GameDetail
FOR EACH ROW
EXECUTE FUNCTION fctMatch();
-- ? Q10). Tester votre trigger en ajoutant de fausses lignes dans la table GameDetail. Pensez bien à vérifier chaque cas possible !
DELETE FROM GameDetail
WHERE idGame = '22101005';
INSERT INTO GameDetail VALUES('22101005','1610612750','1630162','F',NULL,'0 0:36:22',4,10,0.4,3,8,0.375,4,4,1,0,8,8,5,3,1,1,1,15,5);
INSERT INTO GameDetail VALUES('22101005','1610612750','1630183','F',NULL,'0 0:23:54',6,8,0.75,1,3,0.333,1,1,1,2,4,6,0,0,2,2,6,14,10);
INSERT INTO GameDetail VALUES('22101005','1610612750','1626157','C',NULL,'0 0:25:17',4,9,0.444,1,3,0.333,6,8,0.75,1,9,10,0,0,0,3,4,15,14);
INSERT INTO GameDetail VALUES('22101005','1610612750','1627736','G',NULL,'0 0:30:52',4,9,0.444,4,9,0.444,0,0,0,0,3,3,1,1,0,1,4,12,20);
INSERT INTO GameDetail VALUES('22101005','1610612750','1626156','G',NULL,'0 0:33:46',3,13,0.231,1,6,0.167,7,7,1,0,6,6,9,1,0,5,0,14,17);
INSERT INTO GameDetail VALUES('22101005','1610612750','1629675',NULL,NULL,'0 0:23:56',3,8,0.375,1,2,0.5,4,4,1,3,7,10,1,3,2,1,1,11,-7);
INSERT INTO GameDetail VALUES('22101005','1610612750','1629162',NULL,NULL,'0 0:21:00',2,5,0.4,0,1,0,1,1,1,0,1,1,3,3,0,0,1,5,-10);
INSERT INTO GameDetail VALUES('22101005','1610612750','1629669',NULL,NULL,'0 0:21:35',6,13,0.462,2,5,0.4,2,2,1,0,0,0,1,0,0,0,0,16,-5);
INSERT INTO GameDetail VALUES('22101005','1610612750','1627752',NULL,NULL,'0 0:22:53',3,8,0.375,2,5,0.4,3,5,0.6,0,2,2,1,1,0,1,2,11,1);
INSERT INTO GameDetail VALUES('22101005','1610612750','1629006',NULL,NULL,'0 0:0:25',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
INSERT INTO GameDetail VALUES('22101005','1610612750','1630195',NULL,'DNP - Coach''s Decision',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
INSERT INTO GameDetail VALUES('22101005','1610612750','1630233',NULL,'DNP - Coach''s Decision',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
INSERT INTO GameDetail VALUES('22101005','1610612750','1627774',NULL,'DNP - Coach''s Decision',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
INSERT INTO GameDetail VALUES('22101005','1610612748','1629130','F',NULL,'0 0:16:31',1,6,0.167,1,6,0.167,0,0,0,0,0,0,4,0,0,0,3,3,-21);
INSERT INTO GameDetail VALUES('22101005','1610612748','200782','F',NULL,'0 0:23:17',3,7,0.429,0,1,0,0,0,0,4,3,7,0,0,0,3,4,6,-25);
INSERT INTO GameDetail VALUES('22101005','1610612748','1628389','C',NULL,'0 0:33:28',7,12,0.583,0,0,0,5,9,0.556,2,10,12,4,3,0,4,2,19,0);
INSERT INTO GameDetail VALUES('22101005','1610612748','1629216','G',NULL,'0 0:25:23',1,8,0.125,0,5,0,0,0,0,0,1,1,3,2,0,1,2,2,-22);
INSERT INTO GameDetail VALUES('22101005','1610612748','200768','G',NULL,'0 0:37:24',4,12,0.333,2,8,0.25,4,6,0.667,2,5,7,7,0,0,3,2,50,-7);
INSERT INTO GameDetail VALUES('22101005','1610612748','1629639',NULL,NULL,'0 0:36:30',8,19,0.421,6,10,0.6,8,8,1,0,7,7,2,2,0,1,1,45,11);
INSERT INTO GameDetail VALUES('22101005','1610612748','1629622',NULL,NULL,'0 0:31:18',6,12,0.5,5,11,0.455,2,2,1,1,6,7,2,0,0,1,5,19,14);
INSERT INTO GameDetail VALUES('22101005','1610612748','202693',NULL,NULL,'0 0:17:02',3,7,0.429,0,2,0,0,0,0,0,4,4,1,0,0,4,2,6,6);
INSERT INTO GameDetail VALUES('22101005','1610612748','203473',NULL,NULL,'0 0:14:32',1,4,0.25,0,1,0,0,0,0,2,6,8,0,0,1,1,3,2,-9);
INSERT INTO GameDetail VALUES('22101005','1610612748','1629312',NULL,NULL,'0 0:4:36',1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,3,8);
INSERT INTO GameDetail VALUES('22101005','1610612748','2617',NULL,'DNP - Coach''s Decision',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
INSERT INTO GameDetail VALUES('22101005','1610612748','1630209',NULL,'DNP - Coach''s Decision',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
SELECT * FROM BestScorer;
-- ? Q11). Intégrer la création de la table BestScorer et votre trigger au script de création de la base de données NBA. Puis lancer le script pour remplir la table BestScorer pour tous les matchs de la base.
-- C'est fait
-- ? Q12). Quel joueur a marqué le plus de points et combien pendant le match du 22 janvier 2006 où les Lakers ont affronté à domicile léquipe de Toronto ?
-- ! Faux, pas de
-- SELECT count(idPlayer), idPlayer, p.name, p.country
-- FROM BestScorer, Player p
-- WHERE idPlayer = p.id
-- GROUP BY idPlayer, p.name, p.country
-- HAVING count(idPlayer) >= ALL(SELECT count(idPlayer) FROM BestScorer)
-- ORDER BY nbPlayer DESC;
SELECT max(maxPts), idPlayer, p.name, p.country
FROM BestScorer, Player p
WHERE idPlayer = p.id
GROUP BY idPlayer, p.name, p.country
HAVING max(maxPts) = (SELECT max(maxPts) FROM BestScorer);
-- ! Détection et correction derreurs.
-- * Comme nous lavons déjà vu dans de précédents TPs, il y a des incohérences ou des données manquantes dans la base de données.
-- * Nous ne voulons pas modifier les données existantes car, même si nous sommes capables de détecter des incohérences, il nest pas possible de savoir
-- * (sans vérifier chaque match un à un) quelles données sont erronées et quelles données sont exactes. Nous allons plutôt mettre en place des méchanismes permettant
-- * dempêcher ces erreurs de se produire lors de lajout de nouvelles données.
-- ? Q13). Créer un trigger qui vérifie la cohérence des données dune ligne de GameDetail, et les corrigent si nécessaire lors de lajout ou de la modification de celle-ci.
-- ? Plus précisément, ce trigger devra sassurer que :
-- ? — fieldGoalsPrctage est cohérent avec fieldGoalsMade et fieldGoalsAttempted et corriger sa valeur si nécessaire.
-- ? — threePointsPrctage est cohérent avec threePointsMade et threePointsAttempted et corriger sa valeur si nécessaire.
-- ? — freeThrowsPrctage est cohérent avec freeThrowsMade et freeThrowsAttempted et corriger sa valeur si nécessaire.
-- ? — rebounds est cohérent avec offensiveRebounds et defensiveRebounds et corriger sa valeur si nécessaire.
-- ? — points est cohérent avec fieldGoalsMade, threePointsMade, et freeThrowsMade et corriger sa valeur si nécessaire.
-- ? Notez quun lancer franc (freeThrow) vaut 1 point. Un field goal vaut 2 ou 3 points selon la distance du lancer.
-- ? Pour que ces modifications ne se fasse pas sans que lutilisateur nen soit informé, toute modification des valeurs entrées par lutilisateur devra
-- ? être signalée par laffichage dun message de niveau WARNING.
-- ? Q14). Vérifier que votre trigger fonctionne.