Vous êtes sur la page 1sur 36

Spécialité :TS Base de donnée

Matière : Implémentation ORACLE


Semestre : 03

Introduction aux objets d’une BD Oracle

1. SQL : SQL (Structured Query Language), est un langage destiné à la gestion des bases
de données relationnelles. Dans ces cours, nous allons utiliser Oracle comme Système de
Gestion de Base de Données (SGBD).

2. Oracle : Oracle est l’un des SGBD (Système de Gestion de Base de Données) les plus
utilisés. C’est un SGBD riche en termes de fonctionnalités et plus tunable. Il comporte
une large solution d’accès (tout langages et toute technologies) en plus de gestion des
clusters etc…

il faut savoir qu’Oracle comporte plusieurs types d’objets. Les plus utilisés sont les Tables,
les Vues, les Triggers (ou Déclencheurs), les Fonctions, les Procédures et les Packages.
 Tables : Une table est l’objet de la BD où on stocke les données. C’est un tableau à deux
dimensions (Colonne et lignes) où lors de sa création nous devons au moins déclarer une
colonne. Il existe plusieurs type de colonne et je vais vous citer les plus utilisés :
VARCHAR2 (liste de caractère), NUMBER (numérique) et DATE.
 Vues : Les vues sont comme des tables mais dont on ne peut pas insérer ou modifier les
données. En fait les vues sont des sélections de données à partir d’une ou de plusieurs
tables déjà créé avec ou sans des filtres. Ci-dessous un exemple pour mieux comprendre
l’utilité des vues :
Nous avons besoin de faire un reporting à la fin de chaque mois. Ce reporting comporte
les ventes effectué dans le mois courant. Nous pouvons créer alors une vues qui
sélectionne à partir des tables des ventes, des produits, des clients etc.. les lignes dont on
a besoin selon le critère de date qui correspond au mois courant. Cela nous évitera de
rédiger la requête chaque mois
 Trigger : C’est du code PL/SQL (langage de programmation spécifique à Oracle) qui
s’exécute lors d’une MAJ (modification, ajout ou suppression) d’une ou plusieurs lignes
d’une table d’où son nom déclencheur.
 Procédure stocké (Fonction, procédure et package): C’est aussi du code PL/SQL mis
en place pour la manipulation de données.

3. Présentation des objets d’une BD oracle :


– 01 : Les Tables (CREATE ALTER TABLE).
 Les Tables sont les objets qui comportent les données. Comme expliquer dans
l’introduction, une table est composée d’au moins une colonne. Pour créer une table,
nous utilisons la requête « CREATE TABLE »

1
Syntaxe :

CREATE TABLE nom_table (


col_1 type_donnee [NULL|NOT NULL],
col_2 type_donnee [NULL|NOT NULL],
...
col_n type_donnee [NULL|NOT NULL]
);
nom_table : est le nom de la table à créer. Le nom doit être unique dans le schéma. Le nom
est alphanumérique mais ne peut pas commencer par un numéro.
col_n : le nom de la nième colonne. Aussi alphanumérique et ne peut pas commencer par un
numéro.
type_donnee : Le type de la donnée de la colonne (VARCHAR2, DATE, NUMBER etc…).
[NULL|NOT NULL]: cette option n’est obligatoire que si vous voulez que la colonne soit non
vide.
Après la création de la table, nous pouvons modifier sa structure en ajoutant, modifiant ou
supprimant des colonnes

La syntaxe est :
/*Pour ajouter une nouvelle colonne*/
ALTER TABLE nom_table
ADD col_1 type_donnee1;
/*Les nouvelles colonnes sont toujours ajoutées en dernier*/
/*Pour modifier le type de donnée d’une colonne*/
ALTER TABLE nom_table MODIFY col_1 type_donnee2;
/*Pour renommer une colonne*/
ALTER TABLE nom_table RENAME COLUMN col_1 TO col_2;
/*Pour supprimer une colonne*/
ALTER TABLE nom_table DROP COLUMN col_1;

On peut aussi, avec la requête ALTER TABLE, ajouter des contraintes et définir les clés
primaires et étrangères.

/*Pour définir une clé primaire */


ALTER TABLE nom_table ADD CONSTRAINT nom_contrainte PRIMARY KEY
(col_1, col_2, ... col_n);
/*Pour définir une clé étrangère */
ALTER TABLE nom_table ADD CONSTRAINT nom_contrainte FOREIGN KEY
(col_1, col_2, ... col_n) REFERENCES table_parent (col_1, col_2, ... col_n);

2
Passons maintenant aux exemples :
Nous voulons créer une table ou on stockerait les employés :

CREATE TABLE employe (


idemp VARCHAR2(5) NOT NULL,
nom VARCHAR2(20),

prenom VARCHAR2(20),
date_embauche DATE,
solde_conge NUMBER(4,2)
);

Cette commande crée la table employe avec 5 colonnes :

 idemp: attribut non nul, de type alphanumérique. Ce champ ne peut dépasser 5


caractères.
 nom, prenom : attributs alphanumériques de 20 caractères maximum. Ces deux champs
peuvent être vides.
 date_embauche : attribut de type date. Peut être nul.
 solde_conge : attribut du type numérique. Le chiffre à droite (2) correspond au nombre
de chiffres après la virgule. Quant au chiffre à gauche correspond au nombre total de
digite qui peut composer ce nombre en incluant les chiffres après la virgule (exp : 0,01
ou 99,99).
Nous voulons définir la colonne id comme clé primaire :

ALTER TABLE employe ADD CONSTRAINT PK_employe PRIMARY KEY (id);

Nous allons ajouter une nouvelle colonne :

ALTER TABLE employe ADD col_test DATE;

Modifions le type de cette nouvelle colonne :

ALTER TABLE employe MODIFY col_test VARCHAR2(25);

ATTENTION : Pour modifier le type d’une colonne,


il faut s’assurer que les données de cette colonne sont nuls
ou bien ils sont compatibles avec le nouveau type (exp : on peut modifier un NUMBER
en VARCHAR mais on ne peut pas faire le contraire si les données ne sont pas vides)

On va renommer la colonne col_test :

ALTER TABLE employe


RENAME COLUMN col_test TO col_test_2;

Et enfin on va supprimer cette colonne :

ALTER TABLE employe


DROP COLUMN col_test_2;
3
C’est tout pour cette partie. Le prochain cours portera sur le requêtes DML (Requêtes de
manipulation des enregistrements).

– 02 : Les requêtes DML (SELECT, INSERT, UPDATE et DELETE).

Dans ce cours nous allons voir les différentes requêtes qui manipulent les données. Ces
requêtes s’appellent les DML (Data Manipulation Language).
Ils existent deux types de DML :
– Les requêtes de sélection (SELECT)
– Les requêtes de modification (INSERT, UPDATE et DELETE)

SELECT
SELECT est le mot clé utilisé pour sélectionner les données des colonnes depuis une ou
plusieurs tables (FROM) selon des critères de recherche (WHERE) et selon un ordre précis
(ORDER BY).
Reprenons notre table employe du cours précèdent. Nous voulons afficher son contenu sans
aucun critère de recherche :
SELECT id, nom, prenom, date_embauche, solde_conge FROM employe;
Traduisant cette phrase en français: sélectionner le contenu des champs id, nom, prénom,
date_embauche et solde_conge depuis la table employe.
Nous avons sélectionné dans cet exemple toutes les colonnes de la table employe. Nous
pouvons donc réécrire cette requête en remplaçant le nom de toutes les colonnes par *

SELECT * FROM employe;

Dans ce cas, l’ordre d’affichage des colonnes est le même que lors de la création de la table.
Dans ce deuxième exemple, nous avons besoin des prénoms, nom et du solde de congé de
toutes les personnes qui ont été embauchées avant 2015. Nous désirons que le résultat soit trié
par le nom, d’une manière croissante, et par solde de congé d’une maniéré décroissante:

SELECT prenom, nom, solde_conge FROM employe WHERE date_embauche <


'01/01/2015' ORDER BY nom ASC, solde_conge DESC;

Ce qu’il faut retenir de ces exemples:


– Si on désire afficher toutes les colonnes nous pouvons utiliser *
– Les conditions de filtre sont ajoutées après le mot clé WHERE. Seules les données qui
respectent ces conditions vont être affichées.
– Le mot clé ASC, qui signifie ascendant, est facultatif. Le tri sera toujours ascendant même si

4
on ne le met pas. Par contre si on désire faire un tri descendant, il faut absolument ajouter le
mot clé DESC.
Prenons notre dernier exemple, mais nous voulons ajouter une autre condition. En plus de la
date d’embauche, nous souhaitons afficher les employé dont le prénom commence par un A
ou par un B

SELECT prenom, nom, solde_conge FROM employe WHERE date_embauche <


'01/01/2015' AND (prenom LIKE 'A%' OR prenom LIKE 'B%') ORDER BY nom ASC,
solde_conge DESC;
Nous pouvons ajouter dans la clause WHERE les opérateurs logiques pour appliquer le filtre.
L’opérateur AND vérifie que les deux conditions sont vraies, alors que l’opérateur OR ne
vérifie que l’une des deux conditions.
Nous utilisons les parenthèses pour prioriser les conditions. Dans l’exemple ci-dessus, les
conditions du filtre sont touts les employés qui sont embauchés avant le 01/01/2015 et que
leurs prénoms commencent par un A ou bien les employés qui sont embauchés avant le
01/01/2015 et que leurs prénoms commencent par un B.
Il existe d’autre opérateur logique qu’on utilise dans la clause WHERE qu’on va voir en
détails dans d’autre cours.
On va voir aussi dans d’autre cours la sélection de plusieurs tables et les jointures.

INSERT, UPDATE et DELETE

Pour modifier les données d’une table nous utilisons ces trois requêtes :

INSERT : Pour insérer une nouvelle ligne dans une table.


La syntaxe est comme suit :
INSERT INTO nom_de_la_table (col_1, col_2, … col_n)
VALUES (val_1, val_2, … val_n);
nom_de_la_table : est le nom de la table dont on va insérer les données.
col_n : le nom de la nième colonne de la table. Les noms des colonnes sont facultatifs.
L’ordre peut ne pas être le même que celui lors de la création de la table.
val_n : la valeur de la colonne col_n. Cette valeur doit être du même type que la colonne
correspondante.

Au cas où nous voulons insérer une ligne en spécifiant toute les colonnes, nous pouvons écrire
directement :

INSERT INTO nom_de_la_table VALUES (val_1, val_1, … val_n);

Passons aux exemples, insérons une nouvelle ligne dans la table emp :

INSERT INTO emp VALUES (1, 'Nom 1', 'Travail', 1234, '01/01/2015', 1500.20, NULL,
NULL);

5
Nous avons insérer dans cette table une ligne qui comporte:
EMPNO : 1
ENAME : Nom 1
JOB : Travail
MGR : 1234
HIREDATE : 01/01/2015
SAL : 1500,20
COMM : Vide
DEPTNO : Vide

Dans le deuxième exemple nous allons insérer un autre employé mais nous ne disposons que
de son matricule et son nom :

INSERT INTO emp (EMPNO, ENAME) VALUES (2, 'Nom 2');


Les autres colonnes seront insérées comme vide.
UPDATE : Pour modifier les informations d’une table.
La syntaxe est comme suit :
UPDATE nom_de_la_table SET col_1 = val_1, col_2 = val_2, … col_n = val_n
WHERE condition;
nom_de_la_table : est le nom de la table dont on va insérer les données.
col_n : le nom de la nième colonne de la table. L’ordre peut ne pas être le même que celui lors
de la création de la table.
val_n : la nouvelle valeur de la colonne col_n. Cette valeur doit être du même type que la
colonne correspondante.

Exemple :

UPDATE emp SET sal = 2000, hiredate = '01/02/2015'


WHERE empno = 2;

Dans cet exemple nous avons modifié les données « sal » et « hiredate » par 2000 et
01/02/2015 pour l’employé numéro 2.

DELETE : Pour supprimer des lignes d’une table.

La syntaxe est comme suit :

DELETE FROM nom_de_la_table WHERE condition;

Exemple : Nous allons supprimer l’employé 2

DELETE FROM emp WHERE empno = 2;


NB: Si vous ne spécifier pas le WHERE dans les requêtes DELETE et UPDATE, alors
toutes les lignes de la table seront impactées par la MAJ.

Pour valider une MAJ dans la table il faut exécuter la requête COMMIT

COMMIT;

6
Dans le cas ou on veut annuler la MAJ, on exécute la requête ROLLBACK

ROLLBACK;
– 03 : Les jointures (LEFT RIGHT FULL JOIN).
Les jointures permettent de joindre les lignes de plusieurs tables dans la même requête. Pour
mieux expliquer cela, prenons comme exemple deux tables : commandes et lignes
commandes. La table des commandes comporte l’entête de chaque commande (référence de la
commande, date de la commande, client etc…) alors que la table ligne commande comporte
les détails de chaque ligne de commandes (article, quantité, etc…). Pour afficher une
commande au complet, nous devons faire une jointure entre ces deux tables.

Il existe plusieurs types de jointure. Nous allons essayer de les voir toutes en détails :

 Produit cartésien :

Comme en mathématique, le produit cartésien est l’ensemble de tous les couples composé par
les lignes de la table 1 et la table2.

Pour réaliser, cette jointure :

SELECT * FROM table1, table2

Prenons le cas des deux tables EMP et DEPT du schéma SCOTT. Le contenu de ces deux
tables est :

Table EMP :
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17/12/1980 800 20
7876 ADAMS CLERK 7788 23/05/1987 1100 20
7521 WARD SALESMAN 7698 22/02/1981 1250 500 30
7654 MARTIN SALESMAN 7698 28/09/1981 1250 1400 30
7934 MILLER CLERK 7782 23/01/1982 1300 10
7844 TURNER SALESMAN 7698 08/09/1981 1500 0 30
7499 ALLEN SALESMAN 7698 20/02/1981 1600 300 30
7782 CLARK MANAGER 7839 09/06/1981 2450 10
7698 BLAKE MANAGER 7839 01/05/1981 2850 30
7566 JONES MANAGER 7839 02/04/1981 2975 20
7902 FORD ANALYST 7566 03/12/1981 3000 20
7788 SCOTT ANALYST 7566 19/04/1987 3000 20
7839 KING PRESIDENT 17/11/1981 5000 10

7
Table DEPT:
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

Exécutons maintenant le produit cartésien de ces deux tables :

SELECT
EMP.EMPNO, EMP.ENAME , EMP.HIREDATE, EMP.DEPTNO, DEPT.DEPTNO,
DEPT.DNAME, DEPT.LOC
FROM EMP, DEPT;

Le résultat sera :

EMPNO ENAME HIREDATE DEPTNO DEPTNO_1 DNAME LOC


7369 SMITH 17/12/1980 20 10 ACCOUNTING NEW YORK
7499 ALLEN 20/02/1981 30 10 ACCOUNTING NEW YORK
7521 WARD 22/02/1981 30 10 ACCOUNTING NEW YORK
7566 JONES 02/04/1981 20 10 ACCOUNTING NEW YORK
7654 MARTIN 28/09/1981 30 10 ACCOUNTING NEW YORK
7698 BLAKE 01/05/1981 30 10 ACCOUNTING NEW YORK
7782 CLARK 09/06/1981 10 10 ACCOUNTING NEW YORK
7788 SCOTT 19/04/1987 20 10 ACCOUNTING NEW YORK
7839 KING 17/11/1981 10 10 ACCOUNTING NEW YORK
7844 TURNER 08/09/1981 30 10 ACCOUNTING NEW YORK
7876 ADAMS 23/05/1987 20 10 ACCOUNTING NEW YORK
7902 FORD 03/12/1981 20 10 ACCOUNTING NEW YORK
7934 MILLER 23/01/1982 10 10 ACCOUNTING NEW YORK
7369 SMITH 17/12/1980 20 20 RESEARCH DALLAS
7499 ALLEN 20/02/1981 30 20 RESEARCH DALLAS
7521 WARD 22/02/1981 30 20 RESEARCH DALLAS
7566 JONES 02/04/1981 20 20 RESEARCH DALLAS
7654 MARTIN 28/09/1981 30 20 RESEARCH DALLAS
7698 BLAKE 01/05/1981 30 20 RESEARCH DALLAS
7782 CLARK 09/06/1981 10 20 RESEARCH DALLAS
7788 SCOTT 19/04/1987 20 20 RESEARCH DALLAS

8
7839 KING 17/11/1981 10 20 RESEARCH DALLAS
7844 TURNER 08/09/1981 30 20 RESEARCH DALLAS
7876 ADAMS 23/05/1987 20 20 RESEARCH DALLAS
7902 FORD 03/12/1981 20 20 RESEARCH DALLAS
7934 MILLER 23/01/1982 10 20 RESEARCH DALLAS
7369 SMITH 17/12/1980 20 30 SALES CHICAGO
7499 ALLEN 20/02/1981 30 30 SALES CHICAGO
7521 WARD 22/02/1981 30 30 SALES CHICAGO
7566 JONES 02/04/1981 20 30 SALES CHICAGO
7654 MARTIN 28/09/1981 30 30 SALES CHICAGO
7698 BLAKE 01/05/1981 30 30 SALES CHICAGO
7782 CLARK 09/06/1981 10 30 SALES CHICAGO
7788 SCOTT 19/04/1987 20 30 SALES CHICAGO
7839 KING 17/11/1981 10 30 SALES CHICAGO
7844 TURNER 08/09/1981 30 30 SALES CHICAGO
7876 ADAMS 23/05/1987 20 30 SALES CHICAGO
7902 FORD 03/12/1981 20 30 SALES CHICAGO
7934 MILLER 23/01/1982 10 30 SALES CHICAGO
7369 SMITH 17/12/1980 20 40 OPERATIONS BOSTON
7499 ALLEN 20/02/1981 30 40 OPERATIONS BOSTON
7521 WARD 22/02/1981 30 40 OPERATIONS BOSTON
7566 JONES 02/04/1981 20 40 OPERATIONS BOSTON
7654 MARTIN 28/09/1981 30 40 OPERATIONS BOSTON
7698 BLAKE 01/05/1981 30 40 OPERATIONS BOSTON
7782 CLARK 09/06/1981 10 40 OPERATIONS BOSTON
7788 SCOTT 19/04/1987 20 40 OPERATIONS BOSTON
7839 KING 17/11/1981 10 40 OPERATIONS BOSTON
7844 TURNER 08/09/1981 30 40 OPERATIONS BOSTON
7876 ADAMS 23/05/1987 20 40 OPERATIONS BOSTON
7902 FORD 03/12/1981 20 40 OPERATIONS BOSTON
7934 MILLER 23/01/1982 10 40 OPERATIONS BOSTON

Vous verrez que le résultat affiché est l’ensemble des couples composés par les lignes des
deux tables.

9
Dans les cas pratiques, on utilise très rarement ce genre de jointure.

 table1.id = table2.id
Ce genre de jointure est le plus utilisé. Prenons les mêmes tables déjà utilisé ci-dessus :

SELECT
EMP.EMPNO, EMP.ENAME, EMP.HIREDATE, EMP.DEPTNO, DEPT.DEPTNO,
DEPT.DNAME, DEPT.LOC
FROM EMP, DEPT
WHERE EMP.deptno = DEPT.deptno;

Cette jointure est réalisée entre les deux tables EMP et SAL. Généralement les jointures se
font à travers les clés étrangères et primaires des tables. Dans notre cas, deptno est la clé
étrangère dans la table EMP alors qu’elle clé primaire de la table SAL. Du coup, le résultat de
cette requête sera :

EMPNO ENAME HIREDATE DEPTNO DEPTNO_1 DNAME LOC


NEW
7782 CLARK 09/06/1981 10 10 ACCOUNTING YORK
NEW
7839 KING 17/11/1981 10 10 ACCOUNTING YORK
NEW
7934 MILLER 23/01/1982 10 10 ACCOUNTING YORK
7566 JONES 02/04/1981 20 20 RESEARCH DALLAS
7788 SCOTT 19/04/1987 20 20 RESEARCH DALLAS
7902 FORD 03/12/1981 20 20 RESEARCH DALLAS
7369 SMITH 17/12/1980 20 20 RESEARCH DALLAS
7876 ADAMS 23/05/1987 20 20 RESEARCH DALLAS
7499 ALLEN 20/02/1981 30 30 SALES CHICAGO
7521 WARD 22/02/1981 30 30 SALES CHICAGO
7844 TURNER 08/09/1981 30 30 SALES CHICAGO
7698 BLAKE 01/05/1981 30 30 SALES CHICAGO
7654 MARTIN 28/09/1981 30 30 SALES CHICAGO

Vous pouvez constater que toutes les lignes de la table EMP ont été ramenées par la requête.
En plus, les informations relatives au département ont été affichées aussi. Vous pouvez aussi
voir que les données du département 40 n’ont pas été sélectionnées puisqu’aucun employé
n’appartient au département 40.

10
Lançant maintenant cette requête :

SELECT EMPLOYE.EMPNO NUM_EMP, EMPLOYE.ENAME NOM_EMP,


EMPLOYE.JOB POSTE_EMP, MANAGER.ENAME NOM_MANAGER,
MANAGER.JOB POSTE_MANAGER, DEPT.DNAME DEPART
FROM EMP EMPLOYE, EMP MANAGER, DEPT
WHERE EMPLOYE.DEPTNO = DEPT.DEPTNO
AND EMPLOYE.MGR = MANAGER.EMPNO;

Le résultat obtenu est :

POSTE_
NUM_EMP NOM_EMP POSTE_EMP NOM_MANAGER MANAGER
7788 SCOTT ANALYST JONES MANAGER RESEARCH
7902 FORD ANALYST JONES MANAGER RESEARCH
7499 ALLEN SALESMAN BLAKE MANAGER SALES
7521 WARD SALESMAN BLAKE MANAGER SALES
7654 MARTIN SALESMAN BLAKE MANAGER SALES
7844 TURNER SALESMAN BLAKE MANAGER SALES
7934 MILLER CLERK CLARK MANAGER ACCOUNTING
7876 ADAMS CLERK SCOTT ANALYST RESEARCH
7698 BLAKE MANAGER KING PRESIDENT SALES
7566 JONES MANAGER KING PRESIDENT RESEARCH
7782 CLARK MANAGER KING PRESIDENT ACCOUNTING
7369 SMITH CLERK FORD ANALYST RESEARCH

Dans cette requête, en plus de la jointure entre les tables EMP et DEPT, nous avons ajouté
une nouvelle jointure entre la table EMP et elle-même. La condition de cette dernière jointure
est entre l’attribut MGR de la première table EMP (EMPLOYE) et l’attribut EMPNO de la
deuxième table EMP (MANAGER). Nous avons affiché donc les num des employés, leurs
noms, leurs postes, les noms de leurs managers, les postes des managers et les départements
des employés.

Remarque : L’employé 7839 n’a pas a été sélectionné parce que l’attribut MNG est nul.
 INNER JOIN

Les jointures INNER JOIN ou JOIN ont le même résultat que celle du paragraphe précédent.

Syntaxe :

SELECT
*
FROM table1
INNER JOIN table2 ON table1.id = table2.id;

11
Reprenons les deux requête du paragraphe précédent mais en utilisant INNER JOIN:

SELECT
EMP.EMPNO, EMP.ENAME, EMP.HIREDATE, EMP.DEPTNO, DEPT.DEPTNO,
DEPT.DNAME, DEPT.LOC
FROM EMP
INNER JOIN DEPT ON EMP.deptno = DEPT.deptno;

SELECT
EMPLOYE.EMPNO NUM_EMP, EMPLOYE.ENAME NOM_EMP, EMPLOYE.JOB
POSTE_EMP, MANAGER.ENAME NOM_MANAGER, MANAGER.JOB
POSTE_MANAGER, DEPT.DNAME DEPART
FROM EMP EMPLOYE
JOIN EMP MANAGER ON EMPLOYE.MGR = MANAGER.EMPNO
JOIN DEPT ON EMPLOYE.DEPTNO = DEPT.DEPTNO;

La condition de jointure est ajoutée après ON. Nous pouvons ajouter un WHERE après avoir
faire la jointure. Par exemple, nous allons ajouter dans cette dernière requête une condition
pour ne sélectionner que les employés qui ont un poste ANALYST

SELECT
EMPLOYE.EMPNO NUM_EMP, EMPLOYE.ENAME NOM_EMP, EMPLOYE.JOB
POSTE_EMP, MANAGER.ENAME NOM_MANAGER, MANAGER.JOB
POSTE_MANAGER, DEPT.DNAME DEPART
FROM EMP EMPLOYE
JOIN EMP MANAGER ON EMPLOYE.MGR = MANAGER.EMPNO
JOIN DEPT ON EMPLOYE.DEPTNO = DEPT.DEPTNO
WHERE EMPLOYE.JOB = 'ANALYST';

Le résultat obtenu dans ce cas est :

POSTE_
NUM_EMP NOM_EMP POSTE_EMP NOM_MANAGER MANAGER DEPART
7788 SCOTT ANALYST JONES MANAGER RESEARCH
7902 FORD ANALYST JONES MANAGER RESEARCH
 FULL, RIGHT et LEFT JOIN (jointure externe)

Ce type de jointure externe est très intéressant. Dans notre requête qui affiche les employés et leurs
Manager, une ligne n’a pas été sélectionnée. Le Manager de cette ligne est vide. Mais si on voulait
avoir les données de tous les employés (qui ont ou pas un Manager) avec les données de leurs Mangers
s’elles existent, la requête sera alors :

SELECT
EMPLOYE.EMPNO NUM_EMP, EMPLOYE.ENAME NOM_EMP, EMPLOYE.JOB
POSTE_EMP, MANAGER.ENAME NOM_MANAGER, MANAGER.JOB POSTE_MANAGER,
DEPT.DNAME DEPART

12
FROM EMP EMPLOYE
LEFT JOIN EMP MANAGER ON EMPLOYE.MGR = MANAGER.EMPNO
JOIN DEPT ON EMPLOYE.DEPTNO = DEPT.DEPTNO;

Le résultat est :

NUM_EMP NOM_EMP POSTE_EMP NOM_NPLUS1 POSTE_NPLUS1 DEPART


7902 FORD ANALYST JONES MANAGER RESEARCH
7788 SCOTT ANALYST JONES MANAGER RESEARCH
7654 MARTIN SALESMAN BLAKE MANAGER SALES
7844 TURNER SALESMAN BLAKE MANAGER SALES
7521 WARD SALESMAN BLAKE MANAGER SALES
7499 ALLEN SALESMAN BLAKE MANAGER SALES
7934 MILLER CLERK CLARK MANAGER ACCOUNTING
7876 ADAMS CLERK SCOTT ANALYST RESEARCH
7698 BLAKE MANAGER KING PRESIDENT SALES
7566 JONES MANAGER KING PRESIDENT RESEARCH
7782 CLARK MANAGER KING PRESIDENT ACCOUNTING
7369 SMITH CLERK FORD ANALYST RESEARCH
7839 KING PRESIDENT ACCOUNTING

Vous pouvez voir que l’employé 7839 est sélectionné et que les attributs NOM_NPLUS1 et
POSTE_NPLUS1 sont vide.

De la même manière, RIGHT JOIN a le même comportement que LEFT JOIN mais au sens
contraire.

EMP EMPLOYE LEFT JOIN EMP MANAGER ON EMPLOYE.MGR =


MANAGER.EMPNO est équivalent à EMP MANAGER RIGHT JOIN EMP EMPLOYE ON
EMPLOYE.MGR = MANAGER.EMPNO

FULL JOIN est une jointure dans les deux sens. Pour mieux comprendre cette jointure,
faisons l’exemple suivant :

Ajoutons une ligne dans la table EMP

INSERT INTO EMP VALUES (1, 'NOM', 'JOB', 7902, '01/01/1980', 1234, NULL, 60);

Exécutons la requête ci-dessous :

SELECT
EMP.EMPNO, EMP.ENAME, EMP.HIREDATE, EMP.DEPTNO, DEPT.DEPTNO,
DEPT.DNAME, DEPT.LOC FROM EMP
FULL JOIN DEPT ON EMP.deptno = DEPT.deptno;

13
Le résultat sera

EMPNO ENAME HIREDATE DEPTNO DEPTNO_1 DNAME LOC


NEW
7782 CLARK 09/06/1981 10 10 ACCOUNTING YORK
NEW
7839 KING 17/11/1981 10 10 ACCOUNTING YORK
NEW
7934 MILLER 23/01/1982 10 10 ACCOUNTING YORK
7566 JONES 02/04/1981 20 20 RESEARCH DALLAS
7788 SCOTT 19/04/1987 20 20 RESEARCH DALLAS
7902 FORD 03/12/1981 20 20 RESEARCH DALLAS
7369 SMITH 17/12/1980 20 20 RESEARCH DALLAS
7876 ADAMS 23/05/1987 20 20 RESEARCH DALLAS
7499 ALLEN 20/02/1981 30 30 SALES CHICAGO
7521 WARD 22/02/1981 30 30 SALES CHICAGO
7844 TURNER 08/09/1981 30 30 SALES CHICAGO
7698 BLAKE 01/05/1981 30 30 SALES CHICAGO
7654 MARTIN 28/09/1981 30 30 SALES CHICAGO
1 NOM 01/01/1980 60
40 OPERATIONS BOSTON

Vous pouvez constater que toutes les lignes des deux tables sont affichées même ceux qui
n’ont pas d’équivalence.

Pour finir ce cours, il faut savoir que nous pouvons réaliser ces dernières jointures (FULL,
RIGHT et LEFT JOIN) en utilisant les jointures ordinaires. Pour se faire, nous utilisons le
symbole (+)

FULL JOIN correspond à table1.id (+) = table2.id (+)


RIGHT JOIN correspond à table1.id (+) = table2.id
LEFT JOIN correspond à table1.id = table2.id (+)

– 04 : Les fonctions d’agrégation


Les fonctions d’agrégation sont des fonctions utilisées dans les requêtes SQL et qui retournent
toujours un seul résultat. Par exemple, compter les lignes d’une table, retourner le MAX des
valeurs d’une colonne d’une table, etc.

14
 COUNT :

La fonction COUNT sert à compter les lignes d’une table ou d’une requête.

SELECT COUNT(*) FROM EMP ;

COUNT(*)
----------------------
14
Cette fonction ne peut pas retourner une valeur nulle même si la requête ne retourne aucun
résultat :

SELECT COUNT(*) FROM EMP WHERE 1 = 2 ;

COUNT(*)
----------------------
0

Nous pouvons aussi utiliser la fonction COUNT pour compter le nombre d’enregistrement
non vide dans une colonne. Pour cela :

SELECT COUNT(COMM) FROM EMP ;

COUNT(COMM)
----------------------
4

Nous pouvons aussi sélectionner le nombre d’enregistrement distinct dans une colonne en
utilisant :

SELECT COUNT(DISTINCT JOB) FROM EMP ;

COUNT(DISTINCT JOB)
----------------------
5

Nous utilisons DISTINCT pour ne comptabiliser (ou ne sélectionner, dans le cas d’un
SELECT normal) qu’une seule fois les enregistrements en double.

 MAX :

La fonction MAX retourne la valeur la plus grande d’une colonne d’une table ou d’une
sélection

SELECT MAX(SAL) FROM EMP ;


15
MAX(SAL)
----------------------
5000

Il faut savoir que les colonnes nulles sont ignorées dans cette fonction. De plus si jamais nous
exécutons cette fonction sur une colonne dont toutes ses valeurs sont nulles alors le résultat
est nul aussi

SELECT MAX(COMM) FROM EMP WHERE COMM IS NULL ;

MAX(COMM)
----------------------

 MIN :

La fonction MIN retourne la valeur la plus petite d’une colonne d’une table ou d’une sélection

SELECT MIN(SAL) FROM EMP ;

MIN(SAL)
----------------------
800

Comme pour la fonction MAX, les colonnes nulles sont ignorées dans cette fonction. De plus
si jamais nous exécutons cette fonction sur une colonne dont toutes ses valeurs sont nulles
alors le résultat est nul aussi

SELECT MIN(COMM) FROM EMP WHERE COMM IS NULL ;

MIN(COMM)
----------------------

 SUM

Retourne la somme des valeurs d’une colonne d’une table ou d’une sélection. Cette fonction
ne peut être utilisée qu’avec des champs numériques

SELECT SUM(SAL) FROM EMP ;

SUM(SAL)
----------------------

16
29025

Les valeurs nulles sont considéré comme des 0 par cette fonction et la sommes des valeurs
nulles est nul

SELECT SUM(COMM) FROM EMP WHERE COMM IS NULL ;

SUM(COMM)
----------------------

 AVG:

La fonction AVG renvoie la moyenne de toutes les valeurs d’une colonne. AVG ne peut être
utilisé qu’avec des champs numériques

SELECT AVG(SAL) FROM EMP ;

AVG(SAL)
----------------------
2073,214285714285714285714285714285714286

Il faut savoir qu’on ne peut jamais utiliser une fonction d’agrégation dans une requête
SELECT avec d’autre colonne de la table. Par contre, nous pouvons utiliser dans le même
SELECT plusieurs fonctions d’agrégat. Si nous exécutons cette requête

SELECT COUNT(*), MAX(SAL), MIN(SAL), SUM(SAL), AVG(SAL) FROM EMP ;

COUNT(*) MAX(SAL) MIN(SAL) SUM(SAL) AVG(SAL)


-------- -------- -------- -------- ----------
14 5000 800 29025 2073,214285714285714285714285714285714286

Exécutons maintenant la requête ci-dessous

SELECT SAL, COMM, COUNT(*) FROM EMP ;

Erreur commençant à la ligne 1 de la commande :

SELECT SAL, COMM, COUNT(*) FROM EMP

Erreur à la ligne de commande : 1, colonne : 7

Rapport d'erreur :

17
Erreur SQL : ORA-00937: la fonction de groupe ne porte pas sur un groupe simple
00937. 00000 - "not a single-group group function"
*Cause:
*Action:

Nous ne pouvons exécuter ce genre de requête que si on utilise GROUP BY.

Nous verrons dans le prochain cours la requête GROUP BY en détails.

– 05 : GROUP BY HAVING

Dans ce nouveau chapitre, nous allons nous attaquer à la clause GROUP BY. Pour mieux
expliquer cette clause, prenons l’exemple suivant :

Dans la table EMP du schéma SCOTT, nous voulons afficher la somme des salaires (SAL)
pour chaque poste (JOB). Dans cette requête nous avons besoin de grouper les données par
poste pour faire la somme des salaires de chaque poste :
SELECT JOB, SUM(SAL) FROM EMP
GROUP BY JOB;

JOB SUM(SAL)
--------- ----------------------
CLERK 4150
SALESMAN 5600
PRESIDENT 5000
MANAGER 8275
ANALYST 6000
Comme vous pouvez le voir dans le résultat, pour chaque JOB de la table EMP, nous avons
affiché la somme des SAL correspondant.

Nous pouvons grouper autant de colonne que nous voulons, par exemple, nous voulons
afficher la moyenne des SAL pour chaque JOB et MGR et nous allons ordonner le résultat par
JOB, MGR et par la moyenne des SAL :
SELECT JOB, MGR, AVG(SAL) FROM EMP
GROUP BY JOB, MGR
ORDER BY 1, 2, 3;

JOB MGR AVG(SAL)

18
--------- ---------------------- ----------------------
ANALYST 7566 3000
CLERK 7698 950
CLERK 7782 1300
CLERK 7788 1100
CLERK 7902 800
MANAGER 7839 2758,33
PRESIDENT 5000
SALESMAN 7698 1400

Vous pouvez constater que les colonnes sélectionnées sont ceux avec quoi nous regroupons,
et que chaque ligne affichée est unique.
Nous pouvons utiliser le WHERE avec GROUP BY comme suit : nous voulons afficher le
salaire MAX par ville :

SELECT LOC, MAX(SAL) FROM EMP, DEPT


WHERE EMP.DEPTNO = DEPT.DEPTNO
GROUP BY LOC;

LOC MAX(SAL)
------------- ----------------------
NEW YORK 5000
CHICAGO 2850
DALLAS 3000

Essayons maintenant de sélectionner les villes avec un salaire max supérieur ou égal à 3000

SELECT LOC, MAX(SAL) FROM EMP, DEPT


WHERE EMP.DEPTNO = DEPT.DEPTNO
GROUP BY LOC
HAVING MAX(SAL) >= 3000;

LOC MAX(SAL)
------------- ----------------------
NEW YORK 5000
DALLAS 3000

On utilise HAVING pour faire un filtre sur les données du GROUP BY.
Nous pouvons, par exemple avec la requête GROUP BY, détecter les lignes redondantes
d’une table ou d’une sélection : nous allons afficher dans la requête suivante les MGR qui
sont des managers de plus d’une personne

SELECT MGR, COUNT(*)


FROM EMP
GROUP BY MGR
HAVING COUNT(*) > 1;

19
MGR COUNT(*)
---------------------- ----------------------
7839 3
7698 5
7566 2

Ce qu’il faut retenir c’est:


 Les colonnes sélectionnées doivent être les même dans le GROUP BY.
 Le WHERE doit être utilisé avant la clause GROUP BY, alors que HAVING vient après.
 Nous pouvons utiliser avec le GROUP BY plusieurs fonctions d’agrégations.

– 06 : Date et SYSDATE

Dans ce nouveau cours, nous allons voir comment on gère les dates dans Oracle. Comme
mentionné dans mon premier cours, le format date et l’un des formats les plus utilisés.

Donc pour commencer ce cours, nous allons voir comment sélectionner la date du jour (date
système) grâce au mot clé SYSDATE :

 SYSDATE
SELECT SYSDATE FROM DUAL;

SYSDATE
-------------------------
09/02/16

Nous pouvons formater le résultat en utilisant la fonction TO_CHAR(<DATE>, <Format à


afficher>)

 TO_CHAR
SELECT TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS') FROM DUAL;

TO_CHAR(SYSDATE,'DD/MM/YYYYHH24:MI:SS')
---------------------------------------
09/02/2016 22:48:43

Nous pouvons choisir la partie à afficher dans la date en modifiant le format à afficher de la
fonction TO_CHAR:
SELECT
TO_CHAR(SYSDATE, 'DD') JOUR,

20
TO_CHAR(SYSDATE, 'MM') MOIS,
TO_CHAR(SYSDATE, 'YYYY') ANNEE,
TO_CHAR(SYSDATE, 'HH24') HEURE,
TO_CHAR(SYSDATE, 'MI') MINUTE,
TO_CHAR(SYSDATE, 'SS') SECONDE
FROM DUAL;

JOUR MOIS ANNEE HEURE MINUTE SECONDE


---- ---- ----- ----- ------ -------
09 02 2016 22 48 43

Le format à afficher peut être comme suit :

 TO_CHAR(SYSDATE, ‘D’): retourne le numéro du jour dans la semaine.


 TO_CHAR(SYSDATE, ‘DD’) : retourne le numéro du jour dans le mois.
 TO_CHAR(SYSDATE, ‘DY’) : retourne le nom abrégé du jour dans la semaine.
 TO_CHAR(SYSDATE, ‘DAY’) : retourne le nom complet du jour dans la semaine.
 TO_CHAR(SYSDATE, ‘DDD’) : retourne le numéro du jour dans l’année.
 TO_CHAR(SYSDATE, ‘MM’) : retourne le numéro du mois dans l’année.
 TO_CHAR(SYSDATE, ‘MON’) : retourne le nom abrégé du mois.
 TO_CHAR(SYSDATE, ‘MONTH’) : retourne le nom complet du mois.
 TO_CHAR(SYSDATE, ‘YY’) : retourne l’année sur deux digits.
 TO_CHAR(SYSDATE, ‘YYYY’) : retourne l’année sur quatre digits.
 TO_CHAR(SYSDATE, ‘HH’) : retourne l’heure au format 12h.
 TO_CHAR(SYSDATE, ‘HH24’) : retourne l’heure au format 24h.
 TO_CHAR(SYSDATE, ‘MI’) : retourne les minutes.
 TO_CHAR(SYSDATE, ‘SS’) : retourne les secondes.

Nous pouvons combiner plusieurs de ces formats en ajoutant des séparateurs (-/,. ;:) ou bien
du texte à condition que le texte soit entre « " »

SELECT TO_CHAR(SYSDATE, '"Aujourd''hui, nous sommes le " : DAY, DD MONTH


YYYY') FROM DUAL;

TO_CHAR(SYSDATE,'"AUJOURD''HUI,NOUSSOMMESLE":DAY,DDMONTHYYYY')
--------------------------------------------------------------
Aujourd'hui, nous sommes le : MARDI , 09 FÉVRIER 2016
Nous pouvons bien sûr utiliser la fonction TO_CHAR sur un champ de type date

SELECT 'L''employé ' || ENAME || ' a été embauché le ' || TO_CHAR(HIREDATE, 'DAY,
DD MONTH YYYY') FROM EMP ORDER BY HIREDATE;

21
'L''EMPLOYÉ'||ENAME||'AÉTÉEMBAUCHÉLE'||TO_CHAR(HIREDATE,'DAY,DDMON
THYYYY')
--------------------------------------------------------------------------
L'employé SMITH a été embauché le MERCREDI, 17 DÉCEMBRE 1980
L'employé ALLEN a été embauché le VENDREDI, 20 FÉVRIER 1981
L'employé WARD a été embauché le DIMANCHE, 22 FÉVRIER 1981
L'employé JONES a été embauché le JEUDI , 02 AVRIL 1981
L'employé BLAKE a été embauché le VENDREDI, 01 MAI 1981
L'employé CLARK a été embauché le MARDI , 09 JUIN 1981
L'employé TURNER a été embauché le MARDI , 08 SEPTEMBRE 1981
L'employé MARTIN a été embauché le LUNDI , 28 SEPTEMBRE 1981
L'employé KING a été embauché le MARDI , 17 NOVEMBRE 1981
L'employé JAMES a été embauché le JEUDI , 03 DÉCEMBRE 1981
L'employé FORD a été embauché le JEUDI , 03 DÉCEMBRE 1981
L'employé MILLER a été embauché le SAMEDI , 23 JANVIER 1982
L'employé SCOTT a été embauché le DIMANCHE, 19 AVRIL 1987
L'employé ADAMS a été embauché le SAMEDI , 23 MAI 1987

Le résultat retourné par TO_CHAR est de type chaîne de caractère.

Nous pouvons aussi convertir une chaîne de caractère de format date en type DATE par la
fonction TO_DATE(<Chaîne de caractère au format d’une date>, <Format de la date>) :

 TO_DATE
SELECT TO_DATE('01/01/2016', 'DD/MM/YYYY') FROM DUAL;

TO_DATE('01/01/2016','DD/MM/YYYY')
-------------------------
01/01/16

L’intérêt de l’utilisation de TO_DATE est la conversion d’une chaine de caractère en DATE


pour pouvoir manipuler le résultat comme étant une DATE. Par exemple, nous voulons
afficher les employés qui ont été embauché entre le 01/01/1981 et le 31/12/1982 :

SELECT EMPNO, ENAME, HIREDATE FROM EMP WHERE HIREDATE BETWEEN


TO_DATE('01/01/1981', 'DD/MM/YYYY') AND TO_DATE('31/12/1982',
'DD/MM/YYYY') ORDER BY HIREDATE;

EMPNO ENAME HIREDATE


---------------------- ---------- -------------------------
7499 ALLEN 20/02/81
7521 WARD 22/02/81
7566 JONES 02/04/81
7698 BLAKE 01/05/81
7782 CLARK 09/06/81
7844 TURNER 08/09/81

22
7654 MARTIN 28/09/81
7839 KING 17/11/81
7900 JAMES 03/12/81
7902 FORD 03/12/81
7934 MILLER 23/01/82

Nous pouvons aussi manipuler les dates en faisant des soustractions ou des additions :

SELECT SYSDATE, SYSDATE + 1, SYSDATE + 366, SYSDATE - 365 FROM DUAL;

SYSDATE SYSDATE+1 SYSDATE+366 SYSDATE-365


------------ ------------ ------------ ------------
09/02/16 10/02/16 09/02/17 09/02/15

1 correspond à un jour.

Le résultat de TO_DATE est de type DATE.

Il existe plusieurs autres fonctions de date. Ci-dessous quelques exemples:

 LAST_DAY :

Retourne le dernier jour du mois d’une date

SELECT LAST_DAY(SYSDATE), LAST_DAY(TO_DATE('01/01/2016',


'DD/MM/YYYY')) FROM DUAL;

LAST_DAY(SYSDATE) LAST_DAY(TO_DATE('01/01/2016','DD/MM/YYYY'))
------------------------- -------------------------
29/02/16 31/01/16

Le résultat est de type DATE.

 MONTHS_BETWEEN

Retourne le nombre de mois entre deux dates :

SELECT MONTHS_BETWEEN(SYSDATE, TO_DATE('09/02/2015', 'DD/MM/YYYY'))


FROM DUAL;

MONTHS_BETWEEN(SYSDATE,TO_DATE('09/02/2015','DD/MM/YYYY'))
----------------------------------------------------------
12

Le résultat est de type NUMBER.

 EXTRACT

Retourne l’année, le mois, le jour, l’heure, la minute ou la seconde d’une date :

SELECT EXTRACT(YEAR FROM SYSDATE),

23
EXTRACT(MONTH FROM SYSDATE),
EXTRACT(DAY FROM SYSDATE)
FROM DUAL;

EXTRACT(YEARFROMSYSDATE) EXTRACT(MONTHFROMSYSDATE)
EXTRACT(DAYFROMSYSDATE)
------------------------ ------------------------- -----------------------
2016 2 9

Le résultat est de type NUMBER.

PL/SQL est un langage propre à Oracle permettant une interface procédurale. En effet
PL/SQL permet de réaliser les requêtes SQL et de manipuler les résultats obtenus selon notre
besoin via des variables, des tests (if else case), des boucles (while, for, etc…) comme
n’importe quel langage de programmation.

L’avantage du PL/SQL est que le programme que vous réalisez est sur la même couche de la
BD. Ce qui permet une grande souplesse pour utiliser les données de la base.

Le langage PL/SQL est utilisé dans différents objets du SGBD Oracle, à savoir les Triggers,
les Procedures, les Functions et les Packages. Ces objets sont appelés Procédures Stockés
Nous allons voir ces objets dans nos prochains cours.

Nous pouvons aussi écrire un code PL/SQL qui ne soit pas inclut dans la BD. Ce bout de code
est appelé procédures anonyme.

Syntaxe un Bloc PL/SQL


--DECLARE : mot clé facultatif pour la déclaration des variables
DECLARE
<déclaration des variables à utiliser.
peut être vide si aucune variable n'est utilisé dans le code>

24
--BEGIN : mot clé obligatoire qui signifie début du programme
BEGIN

<code à exécuter>

--EXCEPTION : mot clé facultatif pour gérer les exceptions du code


EXCEPTION

<code à exécuter si exception>


--END : mot clé obligatoire qui signifie fin du programme
END;

Dans notre prochain cours, nous allons voir un Bloc PL/SQL plus en details.

– 07-01 : Partie DECLARE PL/SQL

La première partie d’un bloc PL/SQL est la déclaration DECLARE. Dans cette section, et
comme son nom l’indique, nous devons déclarer toutes les variables qu’on veut utiliser. Le
type des variables à déclarer peut être de type SQL (VARCHAR2, DATE, NUMBER, etc…)
ou de type PL/SQL. On peut initialiser aussi une variable dans cette section avec
l’opérateur :=
Exemples:
DECLARE

--variable VAR1 de type NUMBER


VAR1 NUMBER;

--variable VAR2 de type VARCHAR2 de capacité 4000 caractères


VAR2 VARCHAR2(4000);

--variable VAR3 de type DATE initialisée avec la date système


VAR3 DATE := SYSDATE;

Nous pouvons aussi utiliser les variables de type PL/SQL. Par exemple, nous voulons déclarer
une variable qui sera du même type que le champ ENAME de la table EMP et une autre du
même type du champ HIREDATE:

VAR_ENAME EMP.ENAME%TYPE;
VAR_HIREDATE EMP.HIREDATE%TYPE;
Syntaxe:
nom_variable nom_table.nom_colonne%TYPE;
Enfin, nous pouvons aussi déclarer une variable de type une ligne d’une table ou d’un curseur
(nous verrons les curseurs dan un prochain cours) .
Syntaxe:
nom_variable nom_table%ROWTYPE;

25
Exemples:
VAR_EMP EMP%ROWTYPE;
VAR_DEPT DEPT%ROWTYPE;

– 07-02 : Affectations

Deux méthodes d’affectations de variables existent en PL/SQL:

 Affectation normale : Pour affecter une valeur à une variable nous utilisons
l’opérateur :=
VAR1 := 'Valeur 1';
VAR2 := 1234.56;
VAR3 := SYSDATE;

Nous pouvons aussi affecter le résultat d’une fonction à une variable:

VAR4 := UPPER('variable 4');

 INTO : La deuxième méthode d’affectation est utilisation du mot clé INTO dans une
requête SQL:
SELECT SYSDATE INTO DATE_JOUR FROM DUAL;

La valeur de la variable DATE_JOUR correspond à la date système.


Nous pouvons affecter plusieurs variable dans la même requête comme ceci:

SELECT SYSDATE, UPPER('test'), SUBSTR('Test', 1, 1) INTO DATE_JOUR, VAR1,


VAR2 FROM DUAL;

La valeur de VAR1 est TEST et la valeur de VAR2 et T.

 OUT : Il existe aussi une dernière maniéré d’affecter les variables, c’est l’utilisation
des procédures avec un paramètre OUT:

Supposons que nous avons une procédure qui prend une première chaîne de caractère en entré
et la convertit en majuscule puis retourne le résultat dans une autre chaîne de caractère

PROCEDURE(CHAINE1 IN VARCHAR2, CHAINE2 OUT VARCHAR2);

Nous pouvons utiliser cette procédure pour l’affectation d’une variable:

26
VAR1 := 'bonjour';
VAR2 := '';
PROCEDURE(VAR1,VAR2);

La valeur de la variable VAR2 dans notre cas est « BONJOUR ».

– 08 : GRANT et SYNONYM

 GRANT

Les GRANT est un ensemble de droit qu’on accorde à des objets d’un schéma (TABLE,
PROCEDURE, FUNCTION etc…) vers un autre schéma.

Prenons l’exemple de schéma : SCHEMA1 et SCHEMA2. SCHEMA1 dispose des tables


TAB1, TAB2 et TAB3. Nous avons besoin des données de ces tables dans une PROCEDURE
du SCHEMA2. Nous pouvons utiliser ces donnés en donnant le droit de lecture de ces tables
au SCHEMA2. Pour ce faire, nous utilisant l’instruction GRANT sur le SCHEMA1:

La structure d’un PACKAGE est comme suit:

GRANT SELECT ON TABLE TAB1 TO SCHEMA2;


GRANT SELECT ON TABLE TAB2 TO SCHEMA2;
GRANT SELECT ON TABLE TAB3 TO SCHEMA2;

Nous pouvons après utiliser les tables du schéma SCHEMA1 dans SCHEMA2 en ajoutant
avant le nom de ces tables le nom du schéma SCHEMA1

SELECT * FROM SCHEMA1.TAB1;

Nous pouvons aussi donner le droit de MAJ (INSERT, DELETE et UPDATE) de ces tables
au SCHEMA2:

GRANT SELECT, INSERT, DELETE ON TABLE TAB1 TO SCHEMA2;


GRANT SELECT, DELETE ON TABLE TAB2 TO SCHEMA2;
GRANT SELECT, UPDATE, DELETE, INSERT ON TABLE TAB3 TO SCHEMA2;

Dans ce cas de figure, SCHEMA2 a le droit de SELECT, INSERT et DELETE sur la table
TAB1, a le droit de SELECT et DELETE sur la table TAB2 et a le droit de SELECT,
UPDATE, DELETE et INSERT sur la table TAB3.

Avec le GRANT, nous pouvons donner le droit d’exécution d’une FUNCTION,


PROCEDURE ou d’un PACKAGE à un autre schéma:

27
GRANT EXECUTE ON PROCEDURE PROC1 TO SCHEMA2;
GRANT EXECUTE ON FUNCTION FUNC1 TO SCHEMA2;
GRANT EXECUTE ON PACKAGE PKG1 TO SCHEMA2;

Comme pour le GRANT des tables, on peut faire appel à ces procédures stockées en ajoutant
le nom du schéma avant le nom de la procédure:

EXEC SCHEMA1.PROC1;
PS: Les schémas SCHEMA1 et SCHEMA2 doivent être dans la même BD. Sinon on
peut utiliser un autre objet qu’on appelle DBLink.

 SYNONYM

Les SYNONYM sont des noms alternatives aux noms des objets d’une BD ORACLE. On
peut créer un SYNONYM pour le nom d’une table, d’une procédure, d’une vue etc…

L’utilisation des SYNONYM est inintéressante dans le cas de l’utilisation des GRANT. Cela
permet de faire appel aux objets du schéma initial sans ajouter le nom de ce schéma.

Par exemple, on pourra appeler la table TAB1 du schéma SCHEMA1 dans SCHEMA2 sans
ajouter SCHEMA1 avant le nom de la table. Pour ce faire, on execute la commande suivante
dans le schéma SCHEMA2:

CREATE SYNONYM STAB1 FOR SCHEMA1.TAB1;

On pourra alors faire directement appel à notre table SCHEMA1.TAB1 dans SCHEMA2 par
la requête:

SELECT * FROM STAB1;


/*
Le résultat obtenu sera le même que
SELECT * FROM SCHEMA1.TAB1;
*/

De la même maniéré, on peut créer un SYNONYM aux procédures stockées du schéma


SCHEMA1.

– 07-06 : PROCEDURE

Les procédures stockées (PROCEDURE) sont des blocs PL/SQL qui son stockés dans la base
de donnée ORACLE avec un nom unique. Ces procédures comportent un programme qu’on
peut l’appeler dans une autre procédure, d’une fonction, trigger ou d’un programme externe
qui a accès à notre Base de données.

La structure d’une PROCEDURE est comme suit:

28
CREATE [OR REPLACE] PROCEDURE <NOM_PROCEDURE>([VAR1 IN
<TYPE_VAR1>],
[VAR1 IN <TYPE_VAR1>],
....
[VARN OUT <TYPE_VARN>]) AS

[Déclaration variables à utiliser]

BEGIN

[Corps du programme]

END;
/

Pour déclarer une PROCEDURE:

 CREATE : Créé la procédure stockée <NOM_PROCEDURE>


 OR REPLACE : Facultatif mais vaut mieux l’utiliser. Cela permet de recréer la
PROCEDURE <NOM_PROCEDURE> si elle existe déjà.
 PROCEDURE : Mot clé pour définir qu’il s’agit d’une procédure stockée.
 <NOM_PROCEDURE> : Le nom de la PROCEDURE à créer.
 ([VAR1 IN <TYPE_VAR1>], .., [VARN OUT <TYPE_VARN>]) : Les paramètres de
notre PROCEDURE, NOM_VARIABLE, IN ou OUT ou IN OUT et le type du
paramètre (VARCHAR2, NUMBER, DATE, etc…).
 IN : paramètre en entrée.
 OUT : paramètre en sortie.
 IN OUT : paramètre en entrée et en sortie.
 Les paramètres sont facultatifs. Nous pouvons déclarer une PROCEDURE
sans paramètres d’entrées ou de sorties.
 AS : Mot clé pour déclarer le début de la PROCEDURE.
 Variables à utiliser : Déclaration des variables qu’on va utiliser dans notre
PROCEDURE.
 BEGIN : Début du bloc PL/SQL de la PROCEDURE.
 Corps du programme : Bloc PL/SQL de la PROCEDURE.
 END; : Fin de notre PROCEDURE.
 / : Permet de créer la PROCEDURE.

29
On commence par un exemple simple de PROCEDURE qui va nous afficher un message
« Bonjour Cours SQL. »:
CREATE OR REPLACE PROCEDURE BONJOUR_COURSSQL AS
BEGIN
DBMS_OUTPUT.PUT_LINE('Bonjour Cours SQL');
END;
/

La sortie de ce code est :

PROCEDURE BONJOUR_COURSSQL Compilé.

Vous pouvez voir que cette procédure a été créé parmi les objets PROCEDURE de votre
schéma.

Pour faire appel à cette PROCEDURE, nous allons utiliser le bloc PL/SQL suivant:

DECLARE
BEGIN
BONJOUR_COURSSQL;
END;

La sortie de ce code est :

Bonjour Cours SQL

Nous allons créer une nouvelle PROCEDURE qui vérifie si le PARAM1 en entrée est un code
EMP dans notre table EMP du Schéma SCOTT. Si c’est le cas, la procédure affichera un
message en disant que c’est un employé sinon elle affichera un message en disant que ce n’est
pas le cas.
CREATE OR REPLACE PROCEDURE VERIF_EMP (PARAM1 IN
EMP.EMPNO%TYPE) AS
I NUMBER;
BEGIN
SELECT 1 INTO I FROM EMP WHERE EMPNO = PARAM1;
DBMS_OUTPUT.PUT_LINE(PARAM1 || ' existe bien parmi nos employés');
EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE(PARAM1 || ' n''existe pas parmi nos employés');
END;
/

30
On lance notre PROCEDURE avec le paramétré 7788 et 9999:

DECLARE
BEGIN
VERIF_EMP(7788);
VERIF_EMP(9999);
END;

Le résultat est :

7788 existe bien parmi nos employés


9999 n'existe pas parmi nos employés

Dans ce nouveau exemple, nous allons créer une PROCEDURE qui compare deux paramètres
en entrées de type VARCHAR2 sans tenir compte de la casse est retourne le résultat dans un
troisième paramètre sous forme de VRAI ou FAUX:

CREATE OR REPLACE PROCEDURE COMPARE_CHAINE (PARAM1 IN VARCHAR2,


PARAM2 IN VARCHAR2,
RESULTAT OUT VARCHAR2) AS
BEGIN
RESULTAT := 'FAUX';
IF UPPER(PARAM1) = UPPER(PARAM2) THEN
RESULTAT := 'VRAI';
END IF;
END;
/

On lance notre PROCEDURE avec le paramétré « Bonjour COURS SQL » et « Bonjour


Cours Sql »:

DECLARE
CHAINE1 VARCHAR2(200);
CHAINE2 VARCHAR2(200);
RESULT VARCHAR2(200);
BEGIN
CHAINE1 := 'Bonjour COURS SQL';
CHAINE2 := 'Bonjour Cours Sql';
RESULT := NULL;

COMPARE_CHAINE(CHAINE1, CHAINE2, RESULT);

DBMS_OUTPUT.PUT_LINE('Le résultat est ' || RESULT);


END;

Le résultat est :

31
Le résultat est VRAI

Pour finir ce cours, nous allons utiliser un seul paramètre qui est en entrée et en sortie. Dans
cet exemple, nous allons créer une PROCEDURE qui transforme le paramètre en entrée en
majuscule et enlève les espaces qui existent dans ce paramètre:

CREATE OR REPLACE PROCEDURE MAJUSCULE_SUPR_ESPACE_CHAINE


(PARAM1 IN OUT VARCHAR2) AS
BEGIN
PARAM1 := UPPER(PARAM1);
PARAM1 := REPLACE(PARAM1, ' ', '');
END;
/

On lance notre PROCEDURE avec le paramétré » Bo njour Cours Sq l « :

DECLARE
CHAINE1 VARCHAR2(200);
BEGIN
CHAINE1 := ' Bo njour Cours Sq l ';
DBMS_OUTPUT.PUT_LINE('CHAINE1 avant transformation : ' || CHAINE1);

MAJUSCULE_SUPR_ESPACE_CHAINE(CHAINE1);
DBMS_OUTPUT.PUT_LINE('CHAINE1 après transformation : ' || CHAINE1);
END;

Le résultat est :

CHAINE1 avant transformation : Bo njour Cours Sq l


CHAINE1 après transformation : BONJOURCOURSSQL

Dans notre prochain cours nous allons voir les fonctions (FUNCTION) définies par
l’utilisateur.

– 07-07 : FUNCTION

Les FUNCTION comme pour les PROCEDURE sont du bloc PL/SQL stockés dans l’a BD
ORACLE. Les fonctions retournent toujours une valeur d’un type ORACLE définie.

La structure d’une FUNCTION est comme suit:

CREATE [OR REPLACE] FUNCTION <NOM_FUNCTION>([VAR1 IN <TYPE_VAR1>],


[VAR1 IN <TYPE_VAR1>],
....
[VARN OUT <TYPE_VARN>])
RETURN <TYPE_RETOUR>

32
IS

[Déclaration variables à utiliser]

BEGIN

[Corps du programme]

END;
/

Pour déclarer une FUNCTION:

 CREATE : Créé la fonction <NOM_FUNCTION>.


 OR REPLACE : Facultatif mais vaut mieux l’utiliser. Cela permet de recréer la
FUNCTION <NOM_FUNCTION> si elle existe déjà.
 FUNCTION : Mot clé pour définir qu’il s’agit d’une fonction.
 <NOM_FUNCTION> : Le nom de la FUNCTION à créer.
 ([VAR1 IN <TYPE_VAR1>], .., [VARN OUT ]) : Les paramètres de notre
FUNCTION, NOM_VARIABLE, IN ou OUT ou IN OUT et le type du paramètre
(VARCHAR2, NUMBER, DATE, etc…).
 IN : paramètre en entrée.
 OUT : paramètre en sortie.
 IN OUT : paramètre en entrée et en sortie.
 Les paramètres sont facultatifs. Nous pouvons déclarer une FUNCTION sans
paramètres d’entrées ou de sorties.
 IS : Mot clé pour déclarer le début de la FUNCTION.
 Variables à utiliser : Déclaration des variables qu’on va utiliser dans notre FUNCTION.
 BEGIN : Début du bloc PL/SQL de la FUNCTION.
 Corps du programme : Bloc PL/SQL de la FUNCTION.
 END; : Fin de notre FUNCTION.
 / : Permet de créer la FUNCTION .

Il est intéressant de signaler qu’on peut utiliser les paramètres OUT dans les
FUNCTION comme pour les PROCEDURE, mais cela n’empêche pas que les FUNCTION
doivent toujours retourner une valeur par la commande RETURN.

On commence par un exemple simple de FUNCTION qui va nous retourner la date Systéme
sous forme de VARCHAR2 formater en DD/MM/YYYY HH:MI:SS :

CREATE OR REPLACE FUNCTION DATE_DU_JOUR RETURN VARCHAR2 IS


BEGIN

33
RETURN TO_CHAR(SYSDATE, 'DD/MM/YYYY HH24:MI:SS');
END;
/

La sortie de ce code est :

FUNCTION DATE_DU_JOUR compiled

On fait appel à cette fonction dans une requête :

SELECT DATE_DU_JOUR FROM DUAL;

DATE_DU_JOUR
-------------------
03/01/2017 18:33:52

Dans ce deuxième exemple, nous allons créé une fonction qui vérifie si le PARAM1 en entrée
est un code EMP dans notre table EMP du Schéma SCOTT. Si c’est le cas, la fonction
retournera 1 sinon 0.

CREATE OR REPLACE FUNCTION F_VERIF_EMP(PARAM1 IN


EMP.EMPNO%TYPE) RETURN NUMBER IS
I NUMBER;
BEGIN
SELECT 1 INTO I FROM EMP WHERE EMPNO = PARAM1;
RETURN 1;
EXCEPTION WHEN NO_DATA_FOUND THEN
RETURN 0;
END;
/

On lance fonction avec le paramétré 7788 et 9999:


SELECT DECODE(F_VERIF_EMP(7788), 1, 'Existe', 'N''existe pas') N_7788,
DECODE(F_VERIF_EMP(9999), 1, 'Existe', 'N''existe pas') N_9999
from dual;

N_7788 N_9999
------------ ------------
Existe N'existe pas

Dans cet exemple, nous allons créer une fonction qui compare deux paramètres en entrées de
type VARCHAR2 sans tenir compte de la casse est retourne le résultat sous forme de VRAI
ou FAUX:

34
CREATE OR REPLACE FUNCTION F_COMPARE_CHAINE (PARAM1 IN
VARCHAR2,
PARAM2 IN VARCHAR2) RETURN VARCHAR2
IS
BEGIN
IF UPPER(PARAM1) = UPPER(PARAM2) THEN
RETURN 'VRAI';
END IF;
RETURN 'FAUX';
END;
/

On lance la fonction avec le paramétré « Bonjour COURS SQL » et « Bonjour Cours Sql »:

SELECT F_COMPARE_CHAINE('Bonjour COURS SQL', 'Bonjour Cours Sql') FROM


DUAL;

F_COMPARE_CHAINE('BONJOURCOURSSQL','BONJOURCOURSSQL')
-----------------------------------------------------
VRAI

Pour finir, nous allons créer une fonction qui retourne le paramètre en entrée en majuscule et
enlève les espaces qui existent dans ce paramètre:

CREATE OR REPLACE FUNCTION F_MAJUSCULE_SUPR_ESPACE_CHAINE


(PARAM1 IN VARCHAR2)
RETURN VARCHAR2 IS
VAR VARCHAR2(4000);
BEGIN
VAR := REPLACE(UPPER(PARAM1), ' ', '');
RETURN VAR;
END;
/

On lance la fonction avec le paramétré ‘ Bo njour Cours Sq l ‘:

SELECT F_MAJUSCULE_SUPR_ESPACE_CHAINE(' Bo njour Cours Sq l ') FROM


DUAL;

Le résultat est :

F_MAJUSCULE_SUPR_ESPACE_CHAINE('BONJOURCOURSSQL')
-------------------------------------------------
BONJOURCOURSSQL

Dans notre prochain cours nous allons voir les packages.

35
36

Vous aimerez peut-être aussi