Maitriser le SQL chap.01


1 - Introduction à SQL   

Le sigle SQL signifie "Structured Query Language", soit en français "Langage de recherche structuré".
SQL est un langage de gestion des bases de données relationnelles que presque tous les SGBD comprennent. Il a été développé par IBM dans le courant des années 70, et son nom actuel (il s'appelait initialement SEQUEL) date du début des années 80.                 
SQL a été normalisé par l'ANSI (American National Standards Institute) et par l'ISO (International Organization for Standardization). Voici les principales étapes de ce processus :               

  • première norme ANSI en 1986 ;
  • première norme ISO (SQL1) en 1987, révisée en 1989 ;
  • deuxième norme ISO (SQL2) en 1992 ;
  • troisième norme (SQL3) en cours de rédaction depuis 1999 par l'ANSI et l'ISO, après une très longue gestation, et avec beaucoup de retard sur l'événement.
Malgré la normalisation ISO, l'implémentation du SQL par les différents éditeurs de SGBD comporte des différences plus ou moins marquées concernant : 

  • les détails de la syntaxe ;
  • l'écriture des commandes ;
  • le fonctionnement exact des commandes ;
  • l'implémentation de nouveaux types de données (images, animations, vidéos, liens hypertexte, etc.).
Bref, il n'y a qu'un seul langage SQL, mais chaque éditeur de SGBD implémente son propre dialecte. Le "dictionnaire" qui permet de passer d'un dialecte à l'autre s'appelle ODBC (Open Data Base Connectivity). Il a été imaginé par Microsoft, et mis sur le marché en 1993.        
Contrairement à ce que son nom indique, SQL ne sert pas qu'à écrire des requêtes. C'est un langage complet, qui permet de créer des BDD, des tables, de saisir des données et de les corriger, de créer des vues, des index et des états (parfois baptisés "rapports", par francisation de l'anglais "reports"). Sauf erreur de notre part, il ne permet pas de créer des formulaires, parce qu'il a été conçu à une époque ou l'interface graphique n'existait pas sur ordinateur, et parce qu'un formulaire sans interface graphique n'a guère d'intérêt.            
Par contre, dans les SGBD sans interface graphique, le recours à SQL est obligatoire pour toutes les opérations, y compris la création de la BDD, celle des tables, et la saisie des données.
La tentation est donc forte, pour un professeur qui ignore à quels SGBD ses étudiants seront confrontés lorsqu'ils entreront dans la vie active, de faire dans son enseignement une large part à SQL, qui représente l'outil universel de manipulation des données.
Ceci dit, l'interface graphique est tellement entrée dans les moeurs, qu'il parait difficile qu'à terme tous les SGBD n'en soient pas dotés.
En attendant, nous avons adopté une position mixte, en commençant par l'interface graphique, plus facile à appréhender, et en rajoutant à ce tutoriel quatre chapitres consacrés au langage SQL.      

A l'occasion, nous comparerons l'implémentation du SQL d'Access à celle d'Oracle. Comme nous ne disposons pas d'une base Oracle (nos moyens ne nous le permettent pas...), nous nous inspirerons d'un manuel de formation à la version 8 (l'avant-dernière).     

2 - Le langage SQL dans Access

Dans Access, le langage SQL est utilisé par le moteur du SGBD pour traduire en commandes exécutables les instructions que donne l'utilisateur à travers l'interface graphique.
Mais l'utilisateur n'a pas accès à ce code, sauf pour la conception des requêtes, où il peut passer facilement du mode graphique au mode SQL et vice versa.
Nous utiliserons largement cette possibilité dans les trois chapitres suivants.             
Pour les tables, la situation est nettement moins satisfaisante. L'utilisateur qui se sert de l'interface graphique pour créer une table n'a pas accès au code SQL correspondant. Par contre, il dispose d'un éditeur de SQL qui reconnaît les principales commandes concernant la création et la modification des tables, et la saisie des données.       
Cet éditeur, cependant, ne doit pas faire illusion, car il est loin d'être complet. Il ne permet pas de régler dans le détail les propriétés des champs, comme on peut le faire dans l'interface graphique. Il ne permet pas non plus de créer des listes. Il rend donc des services limités.
Il présente cependant de l'intérêt dans les deux cas suivants :

  • l'apprentissage initial du SQL, pour lequel il n'est pas utile d'entrer immédiatement dans les moindres détails ;
  • l'automatisation (via les macros) de certaines opérations relatives aux tables. En effet, le code SQL que nous allons écrire sera enregistré sous forme de requête par le SGBD, et il est très facile de lancer une requête à partir d'une macro.
Évidemment, il est beaucoup plus facile de créer, remplir, modifier, et supprimer une table dans l'interface graphique d'Access qu'en utilisant des commandes SQL.
Mais tous les SGBD ne sont pas dotés d'une interface graphique, et il est bon de savoir se débrouiller sans elle le cas échéant.            

3 - La procédure             

Pour gérer les tables en langage SQL dans Access, il nous faut opérer de la manière suivante :

  1. Dans la fenêtre "Base de données", nous sélectionnons l'objet  "Requêtes". 
  2. Nous effectuons un double clic sur "Créer une requête en mode création", nous refermons la fenêtre "Afficher la table" sans introduire de table et, dans le menu, nous suivons le chemin suivant :            Requête --> Spécifique SQL --> Définition des données             
  3. S'ouvre alors une fenêtre intitulée "Requête1 : Requête Définition des données", dans laquelle nous pouvons écrire du code SQL.          
  4. Pour exécuter ce code, nous cliquons sur l'icône  "Exécuter". 
  5. Pour l'enregistrer, nous cliquons sur  "Enregistrer". Nous constatons alors que le SGBD Access traite notre code comme une requête.  
  6. Pour modifier le code SQL, nous sélectionnons la requête enregistrée précédemment, et nous cliquons sur l'icône   "Modifier". La fenêtre "Requête Définition des données" s'ouvre à nouveau.
Tous les exemples cités dans ce chapitre ont été transportés (par copier/coller) dans Access 2002, et nous avons vérifié leur bon fonctionnement. Vous ne devriez donc pas rencontrer de difficulté pour les reproduire. 

4 - La création et la suppression d'une table      

Dans la fenêtre ouverte grâce à la procédure précédente, nous écrivons notre première commande (ou instruction) SQL, contenant la clause CREATE TABLE, pour créer la table "Personnes" (nous notons qu'un point-virgule marque la fin de la commande) :                     
CREATE TABLE Personnes
(Nom CHAR(20),
Prénom CHAR(20));
Nous exécutons cette commande en cliquant sur l'icône  "Exécuter".
Le fait qu'aucun message ne soit émis signifie que tout s'est bien passé.
Nous sélectionnons l'objet "Table", et nous constatons que :     

  • la table "Personnes" est effectivement créée ;
  • qu'elle possède deux champs de type texte (de 20 caractères au maximum) ;
  • qu'ils sont intitulés "Nom" et "Prénom".
Si nous enregistrons cette commande en cliquant sur l'icône   "Enregistrer", le SGBD Access la traite comme une requête. Devant son nom, il place une icône particulière (, à ne pas confondre avec l'icône "Modifier") pour rappeler qu'il s'agit d'une commande SQL liée à la manipulation des tables.        
Bien entendu, si nous n'exécutons pas la requête, la table "Personnes" ne sera pas créée. Par contre, si la table "Personnes" existe déjà, la commande ne s'exécute pas (la table existante n'est pas écrasée), et le SGBD affiche le message suivant :          
Message "la table existe déjà"
Attention ! Si l'objet "Table" est sélectionné quand vous lancez l'exécution de la commande SQL, la table "Personnes" n'apparaîtra pas (c'est l'éternel problème de la synchronisation dans Access). 
Il suffit de cliquer, dans le menu, sur "Affichage", puis sur "Actualiser", pour que le nom de la table apparaisse.       
Les commandes SQL s'expriment en format libre. Nous pouvons écrire les clauses en minuscules, et nous ne sommes pas tenus d'aller à la ligne pour détailler les champs.
Bien que la précédente présentation (sur trois lignes) soit considérée comme plus lisible, l'expression suivante est parfaitement exacte et s'exécute normalement :             
create table Personnes (Nom char(20),Prénom char(20));
Les conventions relatives aux noms des tables et des champs varient quelque peu d'un SGBD à l'autre. En ce qui concerne plus particulièrement les champs :        

  • le nombre de caractères ne doit pas être trop grand (64 dans Access, 18 à 30 dans d'autres SGBD) ;
  • seuls les lettres, les nombres et le caractère de soulignement sont autorisés. Access admet les caractères accentués. Il admet aussi l'espace, mais le nom du champ doit alors être écrit entre crochets ;
  • certains SGBD requièrent que le nom d'un champ commence par une lettre, mais ce n'est pas le cas d'Access ;
  • les termes faisant partie du vocabulaire du langage SQL sont interdits ("date" par exemple). Ce sont les mots réservés.
Les types de données sont définis dans le DDL (Data Definition Language) de chaque SGBD, et ils varient beaucoup d'un logiciel à l'autre. Dans Access, les mêmes termes ne sont pas toujours utilisés dans l'interface graphique, en VBA et en SQL.
Voici un échantillon représentatif des différentes façons d'exprimer un type de données lors de la création d'une table en SQL dans Access :           

  • Booléen : BIT ;
  • Nombre entier : SHORT (entier), SMALLINT (entier), LONG (entier long), INTEGER (entier long), BYTE (octet) ;
  • Nombre réel : SINGLE (réel simple), DOUBLE (réel double), NUMERIC (réel double) ;
  • Monétaire : CURRENCY, MONEY ;
  • Date/Heure : DATE, TIME, DATETIME ;
  • Texte : VARCHAR (255 caractères), CHAR(n) ou TEXT(n) (n caractères), LONGTEXT (mémo, 32K max.) ;
  • Fichier binaire : LONGBINARY (Objet OLE) ;
  • Compteur : COUNTER (NuméroAuto).
On notera qu'il n'est pas possible de créer un champ de type hypertexte via une commande SQL dans Access. Même remarque en ce qui concerne les listes de choix.            

Pour supprimer une table, on utilise la clause DROP TABLE, comme le montre l'exemple suivant :         
DROP TABLE Personnes;
Attention ! Si l'objet "Table" est sélectionné dans la fenêtre "Base de données" quand vous lancez l'exécution de la commande SQL de suppression, la table "Personnes" ne disparaîtra pas (c'est l'éternel problème de la synchronisation dans Access). 
Il suffit de cliquer, dans le menu, sur "Affichage", puis sur "Actualiser", pour que le nom de la table disparaisse.               

Si nous enregistrons la commande de suppression de table, Access place devant son nom l'icône   spécifique des requêtes SQL liées à la création de tables.          

5 - La modification d'une table 

Il est possible de modifier une table existante. Les exemples les plus classiques concernent l'addition d'une nouvelle colonne et la suppression d'une colonne existante. La commande :           
ALTER TABLE Personnes
ADD Naissance DATE;
permet, lorsqu'on l'exécute, d'ajouter le champ intitulé "Naissance", de type Date/Heure, à la table "Personnes". La variante suivante fonctionne également :         
ALTER TABLE Personnes
ADD COLUMN Naissance DATE;
La clause INIT, qui permet de donner une valeur initiale aux champs ainsi créés, ne fonctionne pas dans Access.
Par défaut, cette valeur initiale est Null. Pour la modifier, il faut utiliser une commande UPDATE (dont nous parlerons au paragraphe 9 ci-dessous).
Pour supprimer la colonne que nous venons de créer, nous utilisons la commande suivante : 
ALTER TABLE Personnes
DROP Naissance;
ou sa variante :
ALTER TABLE Personnes
DROP COLUMN Naissance;
En SQL standard, la commande ALTER TABLE peut aussi être utilisée pour modifier les propriétés d'une colonne existante. Exemple :          
ALTER TABLE Personnes
MODIFY Nom CHAR(40);
mais la clause MODIFY n'est pas reconnue par Access, et l'exécution de la commande ci-dessus entraîne un message d'erreur. L'ignorance de la clause MODIFY enlève à la commande ALTER TABLE une bonne partie de son intérêt dans Access, et l'on se demande pourquoi l'éditeur a fait les choses à moitié.
Nous verrons cependant au paragraphe 8 que la commande ALTER TABLE admet la clause ADD CONSTRAINT, ce qui permet de rajouter une clé ou de créer une relation.

6 - Les propriétés des champs  

Le langage SQL est doté de clauses permettant de définir les propriétés des champs lors de la création d'une table. Mais le moteur d'Access ne les reconnaît pas toutes, loin de là.
Pour empêcher un champ de rester vide, nous utilisons la clause NOT NULL, comme le montre l'exemple suivant :     
CREATE TABLE Personnes
(Nom CHAR(20) NOT NULL,
Prénom CHAR(20));
Après avoir exécuté la commande nous vérifions, dans le propriétés de la table "Personnes" ainsi créée, que le Null est interdit dans le champ "Nom".
Pour qu'un champ soit indexé sans doublons, nous utilisons la clause UNIQUE, comme le montre l'exemple suivant :
CREATE TABLE Personnes
(Nom CHAR(20) UNIQUE,
Prénom CHAR(20));
Après avoir exécuté la commande, nous ouvrons la table "Personnes" en mode modification, nous cliquons sur le champ "Nom", et nous vérifions que la propriété "Indexé :" vaut "Oui - Sans doublons".
En fait, cette clause possède un intérêt limité pour deux raisons :           

  • nous ne pouvons pas donner de nom à l'index. Ceci nous interdit de supprimer l'index via une commande SQL ;
  • nous ne pouvons pas créer d'index multi-champ de cette façon.
Il est donc souvent préférable d'utiliser la commande de création d'index que nous présenterons au paragraphe suivant.               
Pour poser une clé primaire sur un champ, nous utilisons la clause PRIMARY KEY, comme le montre l'exemple suivant :
CREATE TABLE Personnes
(Nom CHAR(20) PRIMARY KEY,
Prénom CHAR(20));
Après avoir exécuté la commande, nous ouvrons la table "Personnes" en mode modification, nous cliquons sur le champ "Nom", et nous vérifions qu'il est effectivement doté de la clé.
Cette commande possède les deux mêmes défauts que la précédente : nous ne sommes pas maîtres du nom de la clé (le système l'appellera Index_976A9AC0_494C_41C1, par exemple...), et nous ne pouvons pas appliquer la clé à plusieurs champs simultanément. Le premier défaut peut être corrigé grâce à la commande suivante :               
CREATE TABLE Personnes
(Nom CHAR(20) CONSTRAINT clé_primaire PRIMARY KEY,
Prénom CHAR(20));
qui permet d'attribuer le nom "clé_primaire" à la clé ainsi créée.
Nous verrons au paragraphe suivant comment placer une clé sur plusieurs champs.           

Les autres clauses permettant de définir les propriétés des champs ne fonctionnent pas dans Access. Il en est ainsi de DEFAULT, qui permet de fixer la valeur par défaut d'un champ, ainsi que de CHECK, qui permet de fixer des contraintes sur le contenu d'un champ (propriété "Valide si").

7 - La clé primaire et l'index       

Pour placer une clé primaire sur un champ, nous pouvons utiliser la clause CONSTRAINT, qui est obligatoirement suivie d'un nom d'index, et que nous avons déjà rencontrée au paragraphe précédent. Créons, par exemple, la table "Personnes" avec une clé primaire (intitulée clé_primaire) sur le champ "Nom".
La commande s'écrit :                        
CREATE TABLE Personnes
(Nom CHAR(20) NOT NULL,
Prénom CHAR(20),
CONSTRAINT clé_primaire PRIMARY KEY(Nom));
L'objet "Table" étant sélectionné, nous cliquons sur l'icône   "Index", et la fenêtre du même nom s'ouvre.
Nous vérifions que la clé est bien nommée "clé_primaire", comme le montre la figure suivante :      
La clé primaire dans l'index
Pour appliquer la clé à deux champs, nous utilisons la syntaxe suivante :           
CREATE TABLE Personnes
(Nom CHAR(20),
Prénom CHAR(20),
CONSTRAINT essai_index PRIMARY KEY(Nom, Prénom));
La création d'un index peut s'effectuer alors que la table existe déjà, mais cela requiert l'usage d'une syntaxe différente.
Créons par exemple un index sur le champ "Nom" de la table "Personnes" :   
CREATE UNIQUE INDEX essai_index
ON Personnes (Nom);
Dans le cas d'un index sur deux champs, cette syntaxe devient :           
CREATE UNIQUE INDEX essai_index
ON Personnes (Nom, Prénom);
Pour supprimer un index, la syntaxe SQL standard s'écrit :        
DROP INDEX Personnes.essai_index;
Mais cette syntaxe standard ne fonctionne pas dans Access. Il faut utiliser la variante suivante :            
DROP INDEX essai_index ON Personnes;

8 - La création et la suppression d'une relation

Pour montrer comment on crée une relation 1-n entre deux tables, nous avons décomposé les opérations en quatre étapes.
Dans un premier temps, nous créons la table "Personnes", avec un champ "Nom", un champ "Prénom", et un champ "Code_Ville" (entier long), en exécutant la commande suivante :                       
CREATE TABLE Personnes
(Nom TEXT(30),
Prénom TEXT(30),
Code_Ville LONG);
Dans un deuxième temps, nous créons la table "Villes", avec un champ "Code_Ville" (NuméroAuto) et un champ "Ville".
Cette table servira de liste externe pour la table "Personnes".
Nous exécutons la commande suivante :           
CREATE TABLE Villes
(Code_Ville COUNTER,
Ville TEXT(30));
Dans un troisième temps, nous modifions la table "Villes" en plaçant une clé primaire sur le champ "Code_Ville", qui servira de côté 1 à la future relation.
Pour ce faire, nous exécutons la commande suivante :   

ALTER TABLE Villes

ADD CONSTRAINT clé_primaire PRIMARY KEY(Code_Ville);
Notons que, si nous ne désirons pas donner un nom à la clé (ici "clé_primaire"), nous pouvons simplifier la commande précédente en l'écrivant ainsi :
ALTER TABLE Villes
ADD PRIMARY KEY(Code_Ville);
Dans un quatrième temps, nous modifions la table "Personnes" en plaçant une clé étrangère, nommée "relation_ville", sur le champ "Code_Ville" de la table "Personnes" (on parle de clé étrangère pour le côté n de la relation), en précisant que le côté 1 de la relation est le champ "Code_Ville" de la table "Villes". Nous exécutons donc la commande suivante :      
ALTER TABLE Personnes
ADD CONSTRAINT relation_ville FOREIGN KEY (Code_Ville) REFERENCES Villes (Code_Ville);
Notons que :    

  • si nous ne désirons pas donner un nom à la relation (ici "relation_ville"), et
  • s'il n'y a pas d'ambiguïté sur le champ qui est du côté 1 de la relation (ici "Code_Ville de la table "Villes")
nous pouvons simplifier la commande précédente en l'écrivant ainsi :
ALTER TABLE Personnes
ADD FOREIGN KEY (Code_Ville) REFERENCES Villes;
Nous vérifions dans la fenêtre  "Relations" qu'une relation 1-n a bien été créée entre les deux tables, avec application de l'intégrité référentielle.              
Nous aurions pu être plus directs, en installant les clés (clé primaire et clé étrangère) dès la création des tables.
Pour la table ville, la commande s'écrit :
CREATE TABLE Villes
(Code_Ville COUNTER PRIMARY KEY,
Ville TEXT(30));
Pour la table "Personnes", la commande s'écrit :
CREATE TABLE Personnes
(Nom TEXT(30),
Prénom TEXT(30),
Code_Ville LONG,
CONSTRAINT relation_ville FOREIGN KEY (Code_Ville) REFERENCES Villes);
Ces deux commandes étant exécutées, nous vérifions dans la fenêtre "Relations" que les deux tables sont présentes avec tous leurs champs, et liées par une relation 1-n.             
La suppression de cette relation s'obtient à l'aide de la commande ALTER TABLE. Dans le cas de la table "Personnes", côté n de la relation "relation_ville" créée précédemment, la commande s'écrit :        
ALTER TABLE Personnes
DROP CONSTRAINT relation_ville;
On notera que les options "Mettre à jour en cascade les champs correspondants" et "Supprimer en cascade les enregistrements correspondants" ne sont pas disponibles.      
En conclusion, la création et la suppression d'une relation sont réalisées grâce à la clause CONSTRAINT appliquée à la table située du côté n de la relation.

9 - La saisie et la correction des données            

Pour saisir des données dans la table "Personnes", la commande SQL utilise la clause INSERT INTO. Les données en mode texte doivent être placées entre guillemets.
Exemple :
INSERT INTO Personnes
VALUES
("Machin","Pierre");
Nous vérifions, après exécution de la commande, que Pierre Machin a bien été introduit dans la table "Personnes".
Si nous enregistrons la commande, le SGBD la fait précéder de l'icône , qui symbolise les requêtes de type "Ajout".
Cependant, si nous essayons de basculer en "Mode création" (le mode graphique), le SGBD Access nous oppose le message suivant :               
En bon français, notre commande ressemble à une requête ajout, elle possède l'icône d'une requête ajout, elle utilise la clause INSERT comme une requête ajout, mais ce n'est pas une requête ajout. Qu'on se le dise !        
Si le Null n'est pas interdit dans les champs de la table "Personnes", nous pouvons introduire un nom sans le prénom correspondant, en opérant de la manière suivante :    
INSERT INTO Personnes (Nom)
VALUES
("Truc");
Pour modifier un enregistrement existant, nous faisons appel à la clause UPDATE (qui signifie "mise à jour" en anglais).
Si, par exemple, nous voulons doter M. Truc de son prénom, nous écrirons :        
UPDATE Personnes
SET Prénom="Henri"
WHERE Nom="Truc";
Si nous enregistrons cette commande, le SGBD Access lui attribue l'icône    caractéristique des requêtes de mise à jour.
C'en est effectivement une, comme nous pouvons le constater en basculant en mode graphique.

Pour supprimer une ligne, nous utilisons la commande basée sur la clause DELETE :     
DELETE FROM Personnes
WHERE Nom="Truc";
Lorsque la clause WHERE est absente, le SGBD supprime tous les enregistrements, laissant la table vide (mais ne la supprimant pas) :           
DELETE FROM Personnes;
Si nous enregistrons ces deux commandes, le SGBD Access fait précéder leur nom de l'icône   caractéristique des requêtes suppression.
Cependant, si nous créons la requête suppression correspondante en mode graphique, et si nous basculons en mode SQL, nous obtenons une syntaxe légèrement différente.

Dans certaines implémentations du langage SQL (mais pas dans Access), on peut omettre la clause FROM qui suit la clause DELETE.               

10 - Conclusion

La création d'une table en SQL n'est pas une travail bien ardu, même s'il est certain qu'une bonne interface graphique simplifie fortement l'opération.
La saisie des informations en SQL, par contre, est une tâche quasi désespérante. A moins que les données ne soient importées, l'usage d'une interface graphique s'impose.             
En ce qui concerne les tables, l'interface graphique du SGBD Access est beaucoup plus développée que son interface SQL.
Nous verrons dans les chapitres suivants que la situation est très différente, et nettement plus équilibrée, pour les requêtes.

Aucun commentaire:

Enregistrer un commentaire