Vous êtes sur la page 1sur 5

UCA ESTS

S3/GI TP2 sur l’héritage et les fonctions sous POSTGRESQL

1) Héritage
-------------------Création des tables villes et Capitales avec héritage simple----------
CREATE TABLE cities (
name text,
population float,
altitude int
);

CREATE TABLE capitals (


state VARCHAR(20))
INHERITS (cities);
--------------------------------Insertion des données---------------------------------------------
INSERT INTO capitals VALUES('Pékin',21150000,49,'Chine'),('Tokyo',1389910,44,'Japon'),
('Moscou',12380664,156,'Russie'),('Le Caire',9540000,187,'Egypte'),('Ankara',
5150072,938,'Turkie'),('Riyad',3182981,612,'Arabie Saoudite'),
('Berlin',3711930,34,'Allemagne'),('Rabat',2134533,135,'Maroc'),
('Madrid',3182981,667,'Espagne');
----ces deux requêtes produisent le même résultat même si l’insertion s’est faite juste au
-- niveau de la table capitals

SELECT * FROM capitals;


SELECT * FROM cities;

DELETE FROM capitals;


---Faisons une insertion dans la table cities
INSERT INTO cities VALUES('Casablanca',3359818,115);
---exécutez la requête suivante
SELECT * FROM cities;

SELECT name, altitude


FROM cities
WHERE altitude >100;
---Le résultat ne permet pas de différencier entre villes et capitales, on utilise alors la clause
ONLY pour avoir les villes uniquement:
SELECT name, altitude
FROM ONLY cities
WHERE altitude >100;
------ Dans certain cas, vous souhaitez savoir de quelle table provient une ligne donnée. Une
colonne système appelée TABLEOID présente dans chaque table vous donne la table
d'origine :
SELECT C.tableoid,C.name, c.altitude
FROM cities c
WHERE c.altitude>100;

--- Si vous souhaitez voir les noms de tables actuelles, vous faites une jointure
avec pg_class. Le catalogue pg_class répertorie les tables et presque tout ce qui a des
colonnes ou qui est similaire à une table. Cela inclut les index (mais voir aussi pg_index), les
séquences (mais voir aussi pg_sequence), les vues, les vues matérialisées, les types
composites et les tables TOAST; voir relkind. Pour voir le contenu de pg_class, exécuter :
SELECT * FROM pg_class;
-----Donc, pour voir si la ville appartient à la classe mère ou à la sous classe, on fait une
jointure entre la classe mère et le catalogue pg_class
SELECT p.relname, c.name, c.altitude
FROM cities c, pg_class p
WHERE c.altitude>100 AND c.tableoid=p.oid;
----ou bien avec une jointure JOIN------------
SELECT p.relname, c.name, c.altitude
FROM cities c JOIN pg_class p ON c.tableoid=p.oid
AND c.altitude>100;

----Il est possible de créer sous Postgresql des tables sans colonnes
CREATE TABLE vehicle (name text);
CREATE TABLE boat () INHERITS (vehicle);
CREATE TABLE car () INHERITS (vehicle);

--héritage multiple: boatcar qui hérite des tables boat et vehicle


CREATE TABLE boatcar () INHERITS (boat,car);
-- NOTICE: merging multiple inherited definitions of column "name"

INSERT INTO boatcar (name) VALUES ('amphibious car');


INSERT INTO vehicle VALUES('ofshore');
INSERT INTO boat VALUES('kadi');

--Taper les instructions suivantes et regarder le résultat:


TABLE boatcar ;--c’est une instruction qui permet de sélectionner tous les enregistrements de
la table
TABLE boat;
TABLE car;
TABLE vehicle ;

2) Fonctions
--------------------------------------Fonctions SQL-------------------------------------
CREATE OR REPLACE FUNCTION addition(integer,integer) RETURNS integer AS
$$ SELECT $1+$2 AS result;
$$ LANGUAGE SQL;

SELECT * FROM addition(4,5);


SELECT addition(4,5);
SELECT * FROM addition(4.5,5);

CREATE TABLE BilletsVendus(


idfseance VARCHAR PRIMARY KEY,
codeTarif VARCHAR,
nombre int);
INSERT INTO BilletsVendus VALUES('S1','CT1',20);
SELECT * FROM BilletsVendus;
---------------------------
CREATE OR REPLACE FUNCTION AjoutVente(VARCHAR,VARCHAR,integer)
RETURNS VOID AS
$$ UPDATE BilletsVendus
SET nombre=nombre+$3
WHERE idfseance=$1 AND codeTarif=$2;
$$ LANGUAGE SQL

SELECT * FROM AjoutVente('S1','CT1',10);

CREATE TABLE Films(


idfilm VARCHAR PRIMARY KEY,
Titre VARCHAR,
duree TIME);
INSERT INTO films VALUES('f1','Harry Potter','02:00:00');
SELECT * FROM Films;
CREATE TABLE Seances(
idseance VARCHAR PRIMARY KEY,
dateseance DATE,
horaire TIME,
idfilm VARCHAR,
FOREIGN KEY(idfilm) REFERENCES Films(idfilm) ON UPDATE CASCADE);
INSERT INTO Seances VALUES('S1','12/10/2019','19:30:00','f1');

SELECT * FROM Seances;


----------------------------------
CREATE OR REPLACE FUNCTION Programme() RETURNS SETOF RECORD AS
' SELECT Titre, dateseance
FROM Films, Seances
WHERE Films.idfilm=Seances.idfilm
' LANGUAGE SQL;

SELECT * FROM Programme() AS (film VARCHAR, jour DATE);


SELECT Programme() AS (film VARCHAR, jour DATE);

-----------------------------------
CREATE TYPE ProgrammeJour AS(titrefilm VARCHAR,horairefilm time);

CREATE OR REPLACE FUNCTION Programme1(DATE) RETURNS SETOF


ProgrammeJour AS
'
SELECT Titre, horaire
FROM Films, Seances
WHERE Films.idfilm=Seances.idfilm
AND dateseance=$1;
' LANGUAGE SQL;
SELECT * FROM Programme1('2019-10-12');
SELECT EXTRACT(DAY FROM dateseance) FROM Seances;
-------------------------Fonctions plpgsql---------------------------------------
type polymorphe : un paramètre spécial $0 est créé. Son type de donnée est le type effectif de
retour de la fonction, déduit d'après les types d'entrée. Ceci permet à la fonction d'accéder à
son type de retour réel.
$0 est initialisé à NULL et peut être modifié par la fonction, de sorte qu'il peut être utilisé
pour contenir la variable de retour si besoin est, bien que cela ne soit pas requis. On peut aussi
donner un alias à $0.
------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION ajoute_trois_valeurs(v1 anyelement,v2 anyelement,v3
anyelement) RETURNS anyelement AS
$$ DECLARE resultat ALIAS FOR $0;
BEGIN
resultat=v1+v2+v3;
RETURN resultat;
END;
$$ LANGUAGE Plpgsql;
SELECT ajoute_trois_valeurs(2.1,4.2,5.1);
SELECT ajoute_trois_valeurs(2,4,5);
--------------------------
CREATE TABLE base
( a integer NOT NULL,
b text,
CONSTRAINT base_pkey PRIMARY KEY (a)
);

CREATE OR REPLACE FUNCTION fusionne_base(cle integer, donnee text) RETURNS


void AS
$$
BEGIN
LOOP
UPDATE base SET b=donnee WHERE a=cle;
IF FOUND THEN
RETURN;
END IF;
BEGIN
INSERT INTO base(a,b) VALUES(cle,donnee);
RETURN;
EXCEPTION WHEN unique_violation THEN
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;
SELECT fusionne_base(6,'tsar');
SELECT fusionne_base(3,'Ali');
SELECT fusionne_base(2,'houda');
SELECT * FROM base;

Travail à faire :
1) Que fait la fonction fusionne_base() ?
2) Soit les tables suivantes :
Employé(numsal, nom, prenom, salaire)
histo_salaires (nom, prenom, ancien-sal, nouveau_sal, date_miseajour)
Ecrire une fonction qui prend en paramètre le nom de l’employé et la date de mise à
Jour de son salaire et renvoie l’ancien et le nouveau salaire.

3) Écrire une fonction moySalaire sans paramètre qui renvoie le salaire moyen des
employés.
4) Utiliser ensuite cette fonction pour afficher les noms et le salaire des employés qui
gagnent plus que le salaire moyen,
5) puis ceux dont le salaire est égal au salaire moyen à 10% près (c'est-à-dire ceux dont le
salaire est compris entre 90% et 110% du salaire moyen).

Vous aimerez peut-être aussi