Oracle est un incontournable dans les DB des grandes organisations. Son SGBD occupe la troisième place dans les parts de marché global. On retrouve souvent le SGBD Oracle dans des entreprises de 10 000+ employés.
« Oracle Multitenant permet à une base de données Oracle Database de fonctionner comme une base de données de conteneurs (CDB). Une base de données de conteneurs consolide plusieurs bases de données enfichables (PDB), une collection portable de schémas, d’objets de schéma et d’objets autres que de schéma. Qu’elles soient déployées on-premise ou dans le cloud, avec Oracle Multitenant, les applications s’exécutent sans changement dans des bases de données enfichables autonomes, ce qui permet d’améliorer l’utilisation des ressources, la gestion et la sécurité globale. »
Définition des concepts ici et là.
https://www.oracle.com/ca-en/database/free/get-started/
docker pull container-registry.oracle.com/database/free:latest # En date du 2023.09.28, latest correspond à la version 23c. docker run -d --name oracle -it -p 1521:1521 -p 5500:5500 -e ORACLE_PWD=password -e ORACLE_CHARACTERSET=AL32UTF8 container-registry.oracle.com/database/free:latest # Méthode avec un lien avec sur dossier local: docker run -d --name oracle-db -it \ -p 1521:1521 -p 5500:5500 \ -e ORACLE_PWD=password \ -e ORACLE_CHARACTERSET=AL32UTF8 \ -v ${PWD}/opt/oracle/oradata:/opt/oracle/oradata \ container-registry.oracle.com/database/free:latest
Référence du CHARACTERSET
Suivre les instructions de cette page
Pour la gestion du SGBD, plusieurs méthodes de connexion au serveur Oracle sont disponibles.
Commençons par utiliser un client de type CLI, proposé par Oracle.
# Pour se connecter à la base de données de conteneurs (CDB): $ docker exec -it oracle sqlplus sys/password@localhost:1521/FREE as sysdba SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Wed Sep 20 15:56:38 2023 Version 23.2.0.0.0 Copyright (c) 1982, 2023, Oracle. All rights reserved. Connected to: Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release Version 23.2.0.0.0 SQL>
# Pour se connecter la première BD enfichable (PDB): sqlplus sys@localhost:1521/FREEPDB1 as sysdba
# Afficher le nom du conteneur courant: SQL> show con_name; CON_NAME ------------------------------ CDB$ROOT # Note: CDB$ROOT est le conteneur racine d'une infrastructure Oracle. # Afficher les bases de données enfichables PDBS/PLUGGABLE DATABASES SQL> show pdbs; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 FREEPDB1 READ WRITE NO # Créer une base de données enfichable SQL> CREATE PLUGGABLE DATABASE CSTJ4205D3 ADMIN USER etudiant IDENTIFIED BY password create_file_dest='/home/oracle'; Pluggable database created. SQL> show pdbs; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 FREEPDB1 READ WRITE NO 4 CSTJ4205D3 MOUNTED # Lister le contenu de la table des utilisateurs: SQL> select name from user$; NAME -------------------------------------------------------------------------------- ACCHK_READ ADM_PARALLEL_EXECUTE_TASK ANONYMOUS ... AUDSYS AUTHENTICATEDUSER NAME -------------------------------------------------------------------------------- AVTUNE_PKG_ROLE BDSQL_ADMIN BDSQL_USER ... DATAPUMP_IMP_FULL_DATABASE DBA ... # Rechercher ETUDIANT SQL> select name from user$ where name='ETUDIANT'; no rows selected # Ou est ETUDIANT ??
NOTE: La requête « select name from user$ where name=’etudiant’; » n’a pas retourné d’enregistrement, pourquoi?
Nous avons pourtant créé une nouvelle base de données ‘CSTJ4205D3‘ avec un compte administrateur ‘etudiant‘.
Justement, le compte ‘etudiant‘ n’est pas dans la BD courante mais bien dans la BD ‘CSTJ4205D3‘.
Il faut se connecter sur cette dernière pour pouvoir localiser l’utilisateur ‘etudiant’.
Procédons
docker exec -it oracle sqlplus sys/password@localhost:1521/CSTJ4205D3 as sysdba # Afficher le nom du conteneur courant: SQL> show con_name; CON_NAME ------------------------------ CSTJ4205D3 # Afficher les bases de données SQL> show pdbs; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 4 CSTJ4205D3 READ WRITE NO # Afficher la liste des utilisateurs: SQL> select name from user$; NAME -------------------------------------------------------------------------------- ACCHK_READ ADM_PARALLEL_EXECUTE_TASK ANONYMOUS ... NAME -------------------------------------------------------------------------------- DV_STREAMS_ADMIN DV_XSTREAM_ADMIN EJBCLIENT ETUDIANT ... # ============================================================================= # NOTE: EN CAS D`ERREUR # ============================================================================= SQL> select name from user$; * ERROR at line 1: ORA-01219: Database or pluggable database not open. Queries allowed on fixed tables or views only. Il faudra OUVRIR la base de données: SQL> alter database open; Database altered. SQL> show pdbs; CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 4 CSTJ4205D3 READ WRITE NO SQL> # ============================================================================= # ============================================================================= # Localiser ETUDIANT dans la table user$ SQL> select name from user$ where name='ETUDIANT'; NAME -------------------------------------------------------------------------------- ETUDIANT SQL>
SQL> GRANT create session TO etudiant; Grant succeeded. SQL> GRANT create table TO etudiant; Grant succeeded. SQL> GRANT unlimited tablespace TO ETUDIANT; Grant succeeded. SQL>
L’utilisateur va maintenant pour créer des sessions (login), créer des tables et insérer des enregistrements. Par contre, il ne pourra pas créer des séquences (Champs de type AUTO-INCREMENT). Il faudra, plus tard ajouter un privilège supplémentaire.
Pour tester ses nouveaux privilèges, il va falloir se connecter avec le compte ‘etudiant’.
NOTE: La liste des privilèges systèmes est disponible ici.
SQL> exit # Noter le nom du compte dans la chaine de connexion: docker exec -it oracle sqlplus etudiant/password@localhost:1521/CSTJ4205D3 SQL*Plus: Release 23.0.0.0.0 - Developer-Release on Wed Sep 20 15:16:14 2023 Version 23.2.0.0.0 Copyright (c) 1982, 2023, Oracle. All rights reserved. Last Successful login time: Tue Sep 19 2023 23:47:32 +00:00 Connected to: Oracle Database 23c Free, Release 23.0.0.0.0 - Developer-Release Version 23.2.0.0.0 SQL> SHOW CON_NAME; CON_NAME ------------------------------ CSTJ4205D3 SQL> show user; USER is "ETUDIANT"
SQL> CREATE TABLE TBL_COURS (NUMERO VARCHAR2(20) NOT NULL, NOM VARCHAR2(60) NOT NULL, PERIODES NUMBER NOT NULL, CONSTRAINT TBL_COURS_PK PRIMARY KEY (NUMERO) ENABLE ); Table created. # Lister les tables: SQL> SHOW TABLES; SP2-0158: unknown SHOW option "TABLES" # VOIR NOTE SQL> SELECT table_name FROM user_tables ORDER BY table_name; TABLE_NAME -------------------------------------------------------------------------------- TBL_COURS
NOTE: Contrairement à MySQL, il n’est pas possible d’utiliser la syntaxe ‘SHOW tables;‘ avec Oracle. Il faut plutôt faire un ‘select‘ sur la table système ‘user_tables‘. Référence
Rappel de la syntaxe:
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
SQL> INSERT INTO tbl_cours VALUES ('420-5D3', 'Sécurité des données', 3); 1 row created. SQL> select * from tbl_cours; NUMERO NOM PERIODES -------------------- -------------------------------- --------- 420-5D3 Sécurité des données 3 SQL>
NOTE: Une modification d’une table dans une session, ne sera pas automatiquement disponible sur d’autres sessions. Pour synchroniser les changements, il faut faire :
SQL> COMMIT WORK; Commit complete.
4.3.2 – À FAIRE (DÉFI) – Trouver une solution pour les caractères étendus non-affichés.
Dans une autre leçon, nous apprendrons à utiliser une application de type GUI, Oracle SQL Developer, pour la gestion du SGBD d’Oracle
Il est possible de changer de context (PDB) avec ALTER SESSION
ALTER SESSION SET CONTAINER = bd_exemple; ALTER SESSION SET CONTAINER = CSTJ4205D3; ALTER SESSION SET CONTAINER = CDB$ROOT; -- La racine de l'infrastructure Au besoin, se connecter au nouveau contexte connect sys as sysdba; ALTER DATABASE OPEN; CREATE USER OT IDENTIFIED BY password; GRANT CONNECT, RESOURCE, DBA TO OT; CONNECT ot@bd_exemple -- le context doit-être nommé -- Pour exécuter un script SQL: SQL>@c:\dbsample\ot_schema.sql
Nous avons une grande collection des oeuvres d’Hergé, plus précisément des albums de Tintin. Nous aimerions tenir une base de données complète des ouvrages d’Hergé et pourvoir interroger la BD avec des requêtes du type « Afficher les albums dans lesquels nous retrouvons le Capitaine Haddock« .
En utilisant le client ‘sqlplus‘ d’Oracle,
A) En utilisant une session sqlplus avec l’utilisateur TINTIN, créer les tables suivantes:
B) Insérer les personnages suivants:
C) Insérer les albums suivants:
D) Renseigner les informations suivantes:
E) Afficher les personnages : Nom et description
F) Afficher les albums : Année, Titre, nombre de pages
G) Afficher la liste des albums par personnage. (Cela est un peu plus difficile 😉)
Note: CTRL F7 = Mise en forme (format)
# Note, pas de clause 'IF EXISTS' sous Oracle 23c # Voir: https://stackoverflow.com/questions/1799128/oracle-if-table-exists DROP TABLE IF EXISTS tbl_animaux; CREATE TABLE tbl_animaux ( id NUMBER GENERATED AS IDENTITY, nom CHAR(30) NOT NULL, PRIMARY KEY (id) ); # Oui bien : CREATE TABLE tbl_animaux ( id NUMBER GENERATED AS IDENTITY (START WITH 1 INCREMENT BY 1 NOCACHE), nom VARCHAR2(30) NOT NULL, PRIMARY KEY (id) ); INSERT INTO tbl_animaux (nom) VALUES ('chien'),('chat'),('cheval'), ('poisson'),('oiseau'),('serpent'); SELECT * FROM tbl_animaux;
-- Exemple utilisant la syntaxe 'legacy' pour les valeurs de type AUTO-INCREMENT. -- Fonctionne avec les versions plus anciennes d'Oracle -- Drop tables if they exist (to avoid conflicts) DROP TABLE OrderItems CASCADE CONSTRAINTS; DROP TABLE Orders CASCADE CONSTRAINTS; DROP TABLE Products CASCADE CONSTRAINTS; DROP TABLE Categories CASCADE CONSTRAINTS; DROP TABLE Customers CASCADE CONSTRAINTS; -- Create Customers Table CREATE TABLE Customers ( customer_id NUMBER PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50), email VARCHAR2(100) UNIQUE, password VARCHAR2(100), -- Hashed and salted password address VARCHAR2(255), phone_number VARCHAR2(20) ); -- Create Categories Table CREATE TABLE Categories ( category_id NUMBER PRIMARY KEY, category_name VARCHAR2(100) UNIQUE ); -- Create Products Table CREATE TABLE Products ( product_id NUMBER PRIMARY KEY, product_name VARCHAR2(100), description CLOB, price NUMBER(10, 2), stock_quantity NUMBER, category_id NUMBER REFERENCES Categories(category_id) ); -- Create Orders Table CREATE TABLE Orders ( order_id NUMBER PRIMARY KEY, customer_id NUMBER REFERENCES Customers(customer_id), order_date TIMESTAMP, status VARCHAR2(20) CHECK (status IN ('processing', 'shipped', 'delivered')) ); -- Create OrderItems Table (to represent items in each order) CREATE TABLE OrderItems ( order_item_id NUMBER PRIMARY KEY, order_id NUMBER REFERENCES Orders(order_id), product_id NUMBER REFERENCES Products(product_id), quantity NUMBER, subtotal NUMBER(10, 2) ); -- Create Indexes for Performance CREATE INDEX idx_customer_email ON Customers(email); CREATE INDEX idx_product_category ON Products(category_id); CREATE INDEX idx_order_customer ON Orders(customer_id); CREATE INDEX idx_order_product ON OrderItems(product_id); -- Create Sequences for Auto-Generating IDs CREATE SEQUENCE customer_seq START WITH 1 INCREMENT BY 1; CREATE SEQUENCE category_seq START WITH 1 INCREMENT BY 1; CREATE SEQUENCE product_seq START WITH 1 INCREMENT BY 1; CREATE SEQUENCE order_seq START WITH 1 INCREMENT BY 1; CREATE SEQUENCE order_item_seq START WITH 1 INCREMENT BY 1;
-- Exemple utilisant la syntaxe 'moderne' pour les valeurs de type AUTO-INCREMENT. -- Drop tables if they exist (to avoid conflicts) DROP TABLE OrderItems CASCADE CONSTRAINTS; DROP TABLE Orders CASCADE CONSTRAINTS; DROP TABLE Products CASCADE CONSTRAINTS; DROP TABLE Categories CASCADE CONSTRAINTS; DROP TABLE Customers CASCADE CONSTRAINTS; -- Create Customers Table CREATE TABLE Customers ( customer_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50), email VARCHAR2(100) UNIQUE, password VARCHAR2(100), -- Hashed and salted password address VARCHAR2(255), phone_number VARCHAR2(20) ); -- Create Categories Table CREATE TABLE Categories ( category_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, category_name VARCHAR2(100) UNIQUE ); -- Create Products Table CREATE TABLE Products ( product_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, product_name VARCHAR2(100), description CLOB, price NUMBER(10, 2), stock_quantity NUMBER, category_id NUMBER REFERENCES Categories(category_id) ); -- Create Orders Table CREATE TABLE Orders ( order_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customer_id NUMBER REFERENCES Customers(customer_id), order_date TIMESTAMP, status VARCHAR2(20) CHECK (status IN ('processing', 'shipped', 'delivered')) ); -- Create OrderItems Table (to represent items in each order) CREATE TABLE OrderItems ( order_item_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, order_id NUMBER REFERENCES Orders(order_id), product_id NUMBER REFERENCES Products(product_id), quantity NUMBER, subtotal NUMBER(10, 2) );
-- Ajout de données dans la BD -- Insert data into Categories Table INSERT INTO Categories (category_name) VALUES ('Electronics'), ('Clothing'), ('Books'); -- Insert data into Customers Table INSERT INTO Customers (first_name, last_name, email, password, address, phone_number) VALUES ('John', 'Doe', 'johndoe@example.com', 'hashed_password', '123 Main St, City, Country', '555-123-4567'), ('Jane', 'Smith', 'janesmith@example.com', 'hashed_password', '456 Elm St, City, Country', '555-987-6543'); -- Insert data into Products Table INSERT INTO Products (product_name, description, price, stock_quantity, category_id) VALUES ('Smartphone', 'High-end smartphone with great features', 699.99, 100, 1), ('Laptop', 'Powerful laptop for work and gaming', 1299.99, 50, 1), ('T-shirt', 'Comfortable cotton T-shirt', 19.99, 200, 2), ('Jeans', 'Stylish and durable jeans', 49.99, 150, 2), ('Book: Introduction to SQL', 'Learn SQL programming', 29.99, 30, 3); -- Insert data into Orders Table INSERT INTO Orders (customer_id, order_date, status) VALUES (1, TIMESTAMP '2023-09-26 10:00:00', 'processing'), (2, TIMESTAMP '2023-09-27 14:30:00', 'shipped'); -- Insert data into OrderItems Table INSERT INTO OrderItems (order_id, product_id, quantity, subtotal) VALUES (1, 1, 2, 1399.98), (1, 3, 3, 59.97), (2, 2, 1, 1299.99); -- --------------------------------------------------------------------- -- Encore un peu plus ... -- --------------------------------------------------------------------- -- Insert data into Categories Table INSERT INTO Categories (category_name) VALUES ('Toys'), ('Sports Gear'), ('Home Appliances'); -- Insert data into Customers Table INSERT INTO Customers (first_name, last_name, email, password, address, phone_number) VALUES ('Alice', 'Johnson', 'alice@example.com', 'hashed_password', '789 Oak St, City, Country', '555-555-5555'), ('Bob', 'Smith', 'bob@example.com', 'hashed_password', '321 Cedar St, City, Country', '555-123-7890'); -- Insert data into Products Table INSERT INTO Products (product_name, description, price, stock_quantity, category_id) VALUES ('Action Figure', 'Collectible action figure', 24.99, 50, 1), ('Soccer Ball', 'Official size and weight soccer ball', 19.99, 100, 2), ('Coffee Maker', 'Programmable coffee maker', 49.99, 30, 3), ('Dress', 'Elegant evening dress', 79.99, 70, 2), ('Book: Python Programming', 'Learn Python programming', 39.99, 25, 3); -- Insert data into Orders Table INSERT INTO Orders (customer_id, order_date, status) VALUES (3, TIMESTAMP '2023-09-28 11:15:00', 'processing'), (4, TIMESTAMP '2023-09-29 16:45:00', 'delivered'); -- Insert data into OrderItems Table INSERT INTO OrderItems (order_id, product_id, quantity, subtotal) VALUES (3, 4, 1, 79.99), (3, 5, 2, 79.98), (4, 3, 1, 49.99), (4, 1, 4, 99.96);
A02.4.1 – Obtenir la liste des commandes détaillées, par client:
SELECT o.order_id, c.customer_id, c.first_name || ' ' || c.last_name AS customer_name, o.order_date, o.status, p.product_name, oi.quantity, oi.subtotal FROM Orders o JOIN Customers c ON o.customer_id = c.customer_id JOIN OrderItems oi ON o.order_id = oi.order_id JOIN Products p ON oi.product_id = p.product_id ORDER BY o.order_id, oi.order_item_id;
A02.4.2 – Liste des status des commandes, incluent le nom des clients:
SELECT o.order_id, c.first_name || ' ' || c.last_name AS customer_name, o.status FROM Orders o JOIN Customers c ON o.customer_id = c.customer_id;
A02.4.3 – Liste des clients qui ont acheté un produit plus d’une fois:
SELECT c.customer_id, c.first_name || ' ' || c.last_name AS customer_name, p.product_id, p.product_name FROM Customers c JOIN Orders o ON c.customer_id = o.customer_id JOIN OrderItems oi ON o.order_id = oi.order_id JOIN Products p ON oi.product_id = p.product_id GROUP BY c.customer_id, c.first_name, c.last_name, p.product_id, p.product_name HAVING COUNT(DISTINCT oi.product_id) > 1;
Voici un schéma de base de données pour gérer une collection de bandes dessinées en utilisant Oracle Database. Le schéma comprendra des tables pour les titres de bandes dessinées, les personnages, les citations par personnage, l’année de publication et les auteurs.
-- Supprimer la table Lecteurs_Albums si elle existe DROP TABLE Lecteurs_Albums; -- Supprimer la table Lecteurs si elle existe DROP TABLE Lecteurs; -- Supprimer la table Citations_Albums si elle existe DROP TABLE Citations_Albums; -- Supprimer la table Citations si elle existe DROP TABLE Citations; -- Supprimer la table Albums_Personnages si elle existe DROP TABLE Albums_Personnages; -- Supprimer la table Personnages si elle existe DROP TABLE Personnages; -- Supprimer la table Albums si elle existe DROP TABLE Albums; -- Supprimer la table Auteurs si elle existe DROP TABLE Auteurs; -- Créer la table Auteurs CREATE TABLE Auteurs ( auteur_id NUMBER PRIMARY KEY, nom VARCHAR2(255) ); -- Créer la table Albums CREATE TABLE Albums ( album_id NUMBER PRIMARY KEY, titre VARCHAR2(255), annee_publication NUMBER, auteur_id NUMBER, FOREIGN KEY (auteur_id) REFERENCES Auteurs(auteur_id), nombre_pages NUMBER, isbn VARCHAR2(20), photo_couverture VARCHAR2(255) ); -- Créer la table Personnages CREATE TABLE Personnages ( personnage_id NUMBER PRIMARY KEY, nom VARCHAR2(100) ); -- Créer la table Citations CREATE TABLE Citations ( citation_id NUMBER PRIMARY KEY, texte CLOB, personnage_id NUMBER, FOREIGN KEY (personnage_id) REFERENCES Personnages(personnage_id) ); -- Créer la table Albums_Personnages CREATE TABLE Albums_Personnages ( album_id NUMBER, personnage_id NUMBER, FOREIGN KEY (album_id) REFERENCES Albums(album_id), FOREIGN KEY (personnage_id) REFERENCES Personnages(personnage_id) ); -- Créer la table Citations_Albums CREATE TABLE Citations_Albums ( citation_id NUMBER, album_id NUMBER, page NUMBER, FOREIGN KEY (citation_id) REFERENCES Citations(citation_id), FOREIGN KEY (album_id) REFERENCES Albums(album_id) ); -- Créer la table Lecteurs CREATE TABLE Lecteurs ( lecteur_id NUMBER PRIMARY KEY, nom VARCHAR2(50), prenom VARCHAR2(50), email VARCHAR2(100) ); -- Créer la table Lecteurs_Albums CREATE TABLE Lecteurs_Albums ( lecteur_id NUMBER, album_id NUMBER, FOREIGN KEY (lecteur_id) REFERENCES Lecteurs(lecteur_id), FOREIGN KEY (album_id) REFERENCES Albums(album_id) );
Ce schéma comprend les tables suivantes :
Albums :
album_id
(clé primaire)titre
(titre de l’album)annee_publication
(année de publication)auteur
(auteur de l’album)nombre_pages
(nombre de pages)isbn
(ISBN de l’album)photo_couverture
(chemin vers la photo de la page couverture)Personnages :
personnage_id
(clé primaire)nom
(nom du personnage)Citations :
citation_id
(clé primaire)texte
(texte de la citation)personnage_id
(clé étrangère vers la table Personnages)Albums_Personnages (table de liaison pour gérer la relation entre les albums et les personnages) :
album_id
(clé étrangère vers la table Albums)personnage_id
(clé étrangère vers la table Personnages)Citations_Albums (table de liaison pour gérer la relation entre les citations et les albums) :
citation_id
(clé étrangère vers la table Citations)album_id
(clé étrangère vers la table Albums)page
(numéro de page où la citation apparaît dans l’album)Lecteurs :
lecteur_id
(clé primaire)nom
(nom du lecteur)prenom
(prénom du lecteur)email
(adresse e-mail du lecteur)Lecteurs_Albums (table de liaison pour enregistrer les albums que les lecteurs ont lus) :
lecteur_id
(clé étrangère vers la table Lecteurs)album_id
(clé étrangère vers la table Albums)Ce schéma vous permettra de gérer une collection de bandes dessinées en enregistrant les détails des titres, des personnages, des citations, des années de publication et des auteurs et des lecteurs.
Ajouter dans la bases de données, les auteurs, 10 albums de Tintin, les personnages suivants: Tintin, Milou, Capitaine Haddock, Allan, Professeur Tournesol, Le colonel Alvarez, Dupond, Dupont, Nestor et Bianca Castafiore. Les albums dans lesquels apparaissent ces personnages. Ajouter 10 citations du Capitaine Haddock avec l’album et la page ou apparait la citation.
-- Ajouter 10 albums de Tintin INSERT INTO Albums (titre, annee_publication, auteur_id, nombre_pages, isbn, photo_couverture) VALUES ('Tintin au pays des Soviets', 1929, 1, 144, '978-2203001016', 'tintin_soviets.jpg'), ('Tintin au Congo', 1931, 1, 62, '978-2203001023', 'tintin_congo.jpg'), ('Tintin en Amérique', 1932, 1, 120, '978-2203001030', 'tintin_amerique.jpg'), ('Les Cigares du Pharaon', 1934, 1, 128, '978-2203001047', 'tintin_cigares_pharaon.jpg'), ('Le Lotus bleu', 1936, 1, 80, '978-2203001054', 'tintin_lotus_bleu.jpg'), ('L''Oreille cassée', 1943, 1, 62, '978-2203001061', 'tintin_oreille_cassee.jpg'), ('L''Île noire', 1938, 1, 62, '978-2203001078', 'tintin_ile_noire.jpg'), ('L''Étoile mystérieuse', 1942, 1, 62, '978-2203001108', 'tintin_etoile_mysterieuse.jpg'), ('Le Secret de La Licorne', 1943, 1, 62, '978-2203001115', 'tintin_secret_licorne.jpg'), ('Le Trésor de Rackham le Rouge', 1944, 1, 62, '978-2203001122', 'tintin_tresor_rackham_rouge.jpg'); -- Ajouter les personnages INSERT INTO Personnages (nom) VALUES ('Tintin'), ('Milou'), ('Capitaine Haddock'), ('Allan'), ('Professeur Tournesol'), ('Le colonel Alvarez'), ('Dupond'), ('Dupont'), ('Nestor'), ('Bianca Castafiore'); -- Associer les personnages aux albums INSERT INTO Albums_Personnages (album_id, personnage_id) VALUES (1, 1), (1, 2), (1, 3), -- Tintin, Milou, Capitaine Haddock dans Tintin au pays des Soviets (2, 1), (2, 2), (2, 3), -- Tintin, Milou, Capitaine Haddock dans Tintin au Congo (3, 1), (3, 2), (3, 3), -- Tintin, Milou, Capitaine Haddock dans Tintin en Amérique (4, 1), (4, 2), (4, 3), -- Tintin, Milou, Capitaine Haddock dans Les Cigares du Pharaon (5, 1), (5, 2), (5, 3), -- Tintin, Milou, Capitaine Haddock dans Le Lotus bleu (6, 1), (6, 2), (6, 3), -- Tintin, Milou, Capitaine Haddock dans L'Oreille cassée (7, 1), (7, 2), (7, 3), -- Tintin, Milou, Capitaine Haddock dans L'Île noire (8, 1), (8, 2), (8, 3), -- Tintin, Milou, Capitaine Haddock dans L'Étoile mystérieuse (9, 1), (9, 2), (9, 3), -- Tintin, Milou, Capitaine Haddock dans Le Secret de La Licorne (10, 1), (10, 2), (10, 3); -- Tintin, Milou, Capitaine Haddock dans Le Trésor de Rackham le Rouge -- Ajouter 10 citations du Capitaine Haddock avec l'album et la page INSERT INTO Citations (texte, personnage_id) VALUES ('Mille milliards de mille sabords !', 3), -- Capitaine Haddock dans Tintin au pays des Soviets ('Tonnerre de Brest !', 3), -- Capitaine Haddock dans Tintin au pays des Soviets ('Mille milliards de mille tonnerres !', 3), -- Capitaine Haddock dans Tintin au pays des Soviets ('Mille sabords !', 3), -- Capitaine Haddock dans Tintin au Congo ('Tonnerre de Brest et de brume !', 3), -- Capitaine Haddock dans Tintin au Congo ('Mille milliards de mille typhons !', 3), -- Capitaine Haddock dans Tintin en Amérique ('Mille milliards de mille boulons !', 3), -- Capitaine Haddock dans Les Cigares du Pharaon ('Mille milliards de mille mille mille sabords !', 3), -- Capitaine Haddock dans Le Lotus bleu ('Mille milliards de mille sabords de tonnerre !', 3), -- Capitaine Haddock dans L'Oreille cassée ('Mille milliards de mille tonnerres de Brest !', 3); -- Capitaine Haddock dans L'Île noire -- Associer les citations aux albums et aux pages -- Utilisez les IDs des citations et des albums correspondants INSERT INTO Citations_Albums (citation_id, album_id, page) VALUES (1, 1, 5), (2, 1, 10), (3, 1, 15), (4, 2, 3), (5, 2, 8), (6, 3, 10), (7, 4, 7), (8, 5, 12), (9, 6, 5), (10, 7, 9); -- Ajouter les lecteurs à la table Lecteurs INSERT INTO Lecteurs (nom, prenom, email) VALUES ('Dévore', 'Page', 'page.devore@example.com'), ('Chapitre', 'Premier', 'premier.chapitre@example.com'), ('Spontanée', 'Lecture', 'lecture.spontanee@example.com');
Ajoutons les lectures suivantes pour Dévore Page; Tintin en Amérique, L’Île noire et Le Crabe aux pinces d’or.
-- Ajout des lectures pour Dévore Page (lecteur_id = 1) INSERT INTO Lectures (lecteur_id, album_id) VALUES (1, 3), -- Tintin en Amérique (1, 7), -- L'Île noire (1, 9); -- Le Crabe aux pinces d'or -- ----------------------------------------------------------------- -- Ou bien, à partir du nom des albums: -- Sélectionner les identifiants d'album pour les albums spécifiques DECLARE v_album_tintin_en_amerique NUMBER; v_album_l_ile_noire NUMBER; v_album_le_crabe_aux_pinces_d_or NUMBER; BEGIN SELECT album_id INTO v_album_tintin_en_amerique FROM Albums WHERE titre = 'Tintin en Amérique'; SELECT album_id INTO v_album_l_ile_noire FROM Albums WHERE titre = 'L''Île noire'; SELECT album_id INTO v_album_le_crabe_aux_pinces_d_or FROM Albums WHERE titre = 'Le Crabe aux pinces d''or'; -- Ajout des lectures pour Dévore Page INSERT INTO Lectures (lecteur_id, album_id) VALUES (1, v_album_tintin_en_amerique), (1, v_album_l_ile_noire), (1, v_album_le_crabe_aux_pinces_d_or); END; / -- --------------------------------------------------------------------- -- Ou encore: DECLARE v_lecteur_id NUMBER; BEGIN SELECT lecteur_id INTO v_lecteur_id FROM Lecteurs WHERE nom = 'Dévore' AND prenom = 'Page'; -- Ajouter les lectures pour "Dévore Page" INSERT INTO Lecteurs_Albums (lecteur_id, album_id) SELECT v_lecteur_id, album_id FROM Albums WHERE titre IN ('Tintin en Amérique', 'L''Île noire', 'Le Trésor de Rackham le Rouge'); COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Lecteur "Dévore Page" non trouvé.'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Erreur lors de l''insertion des lectures : ' || SQLERRM); ROLLBACK; END; /
Ajoutons les lectures suivantes pour Chapitre Premier; Le Secret de La Licorne, Tintin au pays des Soviets
-- Obtenir l'identifiant du lecteur "Chapitre Premier" DECLARE v_lecteur_id NUMBER; BEGIN SELECT lecteur_id INTO v_lecteur_id FROM Lecteurs WHERE nom = 'Chapitre' AND prenom = 'Premier'; -- Obtenir les identifiants des albums DECLARE v_album_id_sl NUMBER; v_album_id_tps NUMBER; BEGIN SELECT album_id INTO v_album_id_sl FROM Albums WHERE titre = 'Le Secret de La Licorne'; SELECT album_id INTO v_album_id_tps FROM Albums WHERE titre = 'Tintin au pays des Soviets'; -- Ajouter les lectures pour "Chapitre Premier" INSERT INTO Lecteurs_Albums (lecteur_id, album_id) VALUES (v_lecteur_id, v_album_id_sl), -- Lecture de "Le Secret de La Licorne" (v_lecteur_id, v_album_id_tps); -- Lecture de "Tintin au pays des Soviets"; COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('Album non trouvé.'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Erreur lors de l''insertion des lectures : ' || SQLERRM); ROLLBACK; END; END; /
-- Afficher toutes les citations du Capitaine Haddock SELECT P.nom AS nom_personnage, C.personnage_id, C.texte AS citation_texte FROM Citations C JOIN Personnages P ON C.personnage_id = P.personnage_id WHERE C.personnage_id = ( SELECT personnage_id FROM Personnages WHERE nom = 'Capitaine Haddock' );
-- Afficher le nom des lecteurs et le nom des albums lus trié par lecteur SELECT l.nom AS nom_lecteur, l.prenom AS prenom_lecteur, a.titre AS titre_album FROM lecteurs l JOIN lecteurs_albums la ON l.lecteur_id = la.lecteur_id JOIN albums a ON la.album_id = a.album_id ORDER BY l.nom, l.prenom, a.titre;
-- Afficher le nombre de lectures des albums SELECT substr(a.titre, 1, 40) AS titre_album, COUNT(la.album_id) AS nombre_de_lectures FROM albums a LEFT JOIN lecteurs_albums la ON a.album_id = la.album_id GROUP BY substr(a.titre, 1, 40) ORDER BY nombre_de_lectures DESC, titre_album;
Auto Incrément avec Oracle pour les anciennes versions
NOTE: L’utilisateur doit posséder le privilège système ‘CREATE SEQUENCE’ pour utiliser la clause ‘GENERATED AS IDENTITY’.