~~stoggle_buttons~~
Ces exercices introduisent les notions suivantes :
Pour vous aider dans les exercices, consultez les tutoriaux SQL du site developpez.com. Et notamment :
Des logiciels pour créer un dictionnaire des données, dessiner des MCD et générer automatiquement les modèles logiques, physiques et les ordres SQL de création des tables. Ces deux logiciels demandent que Java (machine virtuelle) soit installée sur votre poste :
Voici un lien vers un document PDF intéressant qui remet en perspective tout le vocabulaire abordé Lundi :
livre0(titre, auteur, editeur, annee_parution, isbn, prix)
Colonne | Type |
---|---|
titre | varchar(100) |
auteur | varchar(300) |
editeur | varchar(100) |
annee_parution | INTEGER (INT en SQLite) |
prix | DOUBLE (REAL en SQLite) |
isbn | varchar(20) |
Vous pouvez recréer une base ou utiliser la base existante. <spoiler|Solution>
F:\>cd __2012_2013\_PREPAS\jeudi\sqlite3\ F:\__2012_2013\_PREPAS\jeudi\sqlite3>sqlite3 base_livres.sqlite3 SQLite version 3.7.17 2013-05-20 00:56:22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables sqlite>
CREATE TABLE livre0(titre VARCHAR(100) NOT NULL, isbn VARCHAR(100), auteur VARCHAR(300), annee_parution INT, prix DOUBLE, editeur VARCHAR(100));
sqlite> .tables livre0 sqlite>
</spoiler>
Utilisez un script SQL avec une vingtaine d'ouvrages d'éditeurs et d'auteurs différents mais aussi avec "doublons" ou "triplés" sur les dates, éditeurs, auteurs.
Quelques données: Design Patterns: Elements of Reusable Object-Oriented Software; Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides;1994;Addison-Wesley Professional;ISBN10 : 0201634988 UML 2 en action , De l'analyse des besoins à la conception ;Pascal Roques, Franck Vallée;2007;Eyrolles;ISBN10 : 2212121040 UML en action , De l'analyse des besoins à la conception;Pascal Roques, Franck Vallée;2000;Eyrolles;ISBN-10 : 2212091273 UML pour les décideurs;Franck Vallée;2005;Eyrolles;ISBN-10 : 2212116217 <spoiler|Solution : >
INSERT INTO livre0 VALUES('UML 2 en action ,De l''analyse des besoins à la conception', '2212121040','Pascal Roques, Franck Vallée', 2007, 42.95, 'Eyrolles');
Lorsqu'on désire ne renseigner que quelques colonnes, on indique leurs noms à la suite du nom de la table
INSERT INTO livre0(titre,isbn) VALUES('Design Patterns: Elements of Reusable Object-Oriented Software','0201634988');
</spoiler>
Ajoutez un livre ou deux livres dont vous ne connaissez que le titre et l'auteur. <spoiler|Solution : >
INSERT INTO livre0(titre,auteur) VALUES('Le Seigneur des Anneaux','Tolkien'); INSERT INTO livre0(titre,auteur) VALUES('Cryptonomicon','Neal Stephenson');
</spoiler>
N'afficher que quelques colonnes d'une table : titre et auteur par exemple. <spoiler|Solution : >
SELECT titre, auteur FROM livre0;
</spoiler>
N'afficher que certaines lignes d'une requête (table ou jointure) : liste des titres de 2007. <spoiler|Solution >
SELECT * FROM livre0 WHERE annee_parution=2007;
SELECT titre, auteur, editeur FROM livre0 WHERE annee_parution=2007;
</spoiler> Affichez les livres dont l'éditeur ou l'année de parution ou le prix n'ont pas été renseignés. <spoiler|Solution >
SELECT * FROM livre0 WHERE editeur IS NULL; Le Seigneur des Anneaux||Tolkien|||SELECT titre, auteur FROM livre0 WHERE annee_parution IS NULL; SELECT titre, auteur FROM livre0 WHERE prix IS NULL;
</spoiler>
AND, OR, NOT, LIKE, …
Exemples de requêtes :
Eyrolles
, parus en 2007 ;Python
;<spoiler|Solution >
SELECT titre, auteur FROM livre0 WHERE editeur IS NULL OR annee_parution IS NULL OR prix IS NULL;
</spoiler>
Cette table est elle en 1ère Forme Normale, dans les différents cas évoqués ci-dessous :
Solutions : que devez vous faire dans chacun de ces 3 cas ?
Voici le MCD correspondant :
Il s'agit, ici de vous familiariser avec les notions de clés primaires et étrangères et de jointure entre tables dans les requêtes SQL.
editeur(num_editeur, nom_editeur)
Attention, il s'agit de la colonne : num_editeur.
livre(num, titre, auteur, fk_num_editeur#, annee_parution, prix)
num
signifie que la colonne est clé primaire.
fk_num_editeur#
: Le caractère dièse (#) signifie que fk_num_editeur (le numéro éditeur) est une clé étrangère.
Vous chercherez dans la documentation de SQLite3 comment déclarer une clé étrangère : http://www.sqlite.org/foreignkeys.html et trouverez ici : des liens vers de la documentation SQLite.
Remarque : SQLite ne respecte pas entièrement le santard SQL92 : http://stackoverflow.com/questions/1884818/how-do-i-add-a-foreign-key-to-an-existing-sqlite-3-6-21-table
Colonne | Type | Commentaires |
---|---|---|
num_editeur | type compteur auto-incrémenté | |
num | type compteur auto-incrémenté | |
titre | varchar(100) NOT NULL | valeur obligatoire |
nom_editeur | varchar(100) NOT NULL | valeur obligatoire |
auteur | varchar(100) | |
fk_num_editeur | entier | INTEGER ou INT (en Sqlite3) |
annee_parution | entier | INTEGER ou INT (en Sqlite3) |
prix | réel | DOUBLE |
<spoiler |Solution>
F:\>cd __2012_2013\_PREPAS\jeudi\sqlite3\ F:\__2012_2013\_PREPAS\jeudi\sqlite3>sqlite3 base_livres.sqlite3 SQLite version 3.7.17 2013-05-20 00:56:22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .tables editeur livre sqlite> .schema
Affichage de
CREATE TABLE editeur( num_editeur INTEGER PRIMARY KEY , nom_editeur VARCHAR(100) NOT NULL ); CREATE TABLE livre(num_livre INTEGER PRIMARY KEY , titre VARCHAR(100) NOT NULL, isbn VARCHAR(100) NOT NULL, auteur VARCHAR(300), annee_parution INT, prix DOUBLE, fk_num_editeur INTEGER, FOREIGN KEY (fk_num_editeur) REFERENCES editeur(num_editeur)); sqlite>
</spoiler>
Vous pouvez copier et modifier votre script de l'exercice précédent.
Attention : veillez à respecter la cohérence entre les tables.
Vous pouvez, aussi, faire un INSERT à partir d'un SELECT sur la table livre0.
INSERT …. INTO table1 .. SELECT ….. FROM table2 WHERE …..;
\\Attention : veillez à respecter la cohérence entre les tables. Voir ici : http://www.sqlite.org/lang_insert.html
Remarque pour les clés étrangères : pour SQLIte, il est impératif de préciser en début de session :
sqlite>PRAGMA foreign_keys = ON;
Sinon les contraintes de clés étrangères ne seront pas vérifiées.
<spoiler | Solution>
SELECT * INTO livre FROM livre0; ou CREATE TABLE livre AS SELECT * FROM livre0
</spoiler>
<spoiler | Un exemple plus complexe >
sqlite> SELECT * FROM livre; 1|Python 2|222222|BBBBB|2007|22.225|2 2|Python et PyQT|444444|DDDDD|2007|22.22|2 3|Python 3|333333|CCCCC|2010|33.33|1 sqlite> SELECT * FROM livre0; UML 2 en action ,De l'analyse des besoins à la conception|2212121040|Pascal Roques, Franck Vallée|2007|42.95|Eyrolles Le Seigneur des Anneaux||Tolkien||| sqlite> INSERT INTO livre0(titre,auteur) VALUES('Cryptonomicon','Neal Stephenson'); sqlite> insert into livre0 select titre, isbn, auteur, annee_parution, prix, nom_editeur f rom livre INNER JOIN editeur ON editeur.num_editeur = livre.fk_num_editeur; sqlite> select * from livre0; UML 2 en action ,De l'analyse des besoins à la conception|2212121040|Pascal Roques, Franck Vallée|2007|42.95|Eyrolles Le Seigneur des Anneaux||Tolkien||| Cryptonomicon||Neal Stephenson||| Python 2|222222|BBBBB|2007|22.225|Dunod Python et PyQT|444444|DDDDD|2007|22.22|Dunod Python 3|333333|CCCCC|2010|33.33|Eyrolles sqlite>
</spoiler>
Utilisez directement l'ordre INSERT en "ligne de commandes". Evitez les accents pour pouvoir réutiliser votre base sous Windows et en Python.
Essayez de :
Effectuez les mêmes requêtes que dans l'exercice 1, mais en prenant en compte "l'aspect jointure". Conseil : ajoutez un éditeur qui n'a pas encore de livre stocké dans votre bibliothèque et essayez des jointures externes : gauche, droite et complète.
Requêtes : Affichez le nombre de livres par éditeur : afficher le nom de l'éditeur et le nombre de lignes. Affichez le prix moyen d'un livre par éditeur : afficher le nom de l'éditeur et le prix moyen.
Créez une table auteur
et liez la à la table livre
.
Posez les contraintes d'intégrité (clés primaires et étrangères).
Insérez des données qui respectent et/ou ne respectent pas les contraintes d'intégrité.
Attention : le MCD fait apparaître une association (un lien) entre ces deux tables, mais les cardinalités sont (1,N) de chaque côté.
Vous pouvez maintenant passer à l'Écriture de requêtes sur une base existante.