Le langage SQL : une introduction
Le langage SQL, pour Simple Query Language, est le langage le plus répandu pour accéder à une base de données. Que vous utilisiez un serveur de base de données de type Oracle, Microsoft SQL Server, mySQL, Microsoft Access ou autre, le langage utilisé pour accéder à la base de données reste le même à l'exception de différences très mineures.
Plusieurs types d'opérations peuvent être exécutées sur une base de données. Certaines commandes permettent de modifier la structure de la base de données : créer une table, supprimer une table ajouter ou enlever des colonnes à une table, etc. Ces commandes ne seront pas traitées dans ce document. D'autres commandes permettent d'ajouter, de supprimer, de modifier ou de rechercher des données dans la BD.
Une base de données peut être vue comme un ensemble de tableaux à deux dimensions, les tables inter-reliés contenant différentes données. Chaque table contient un certain nombre de colonnes, les champs. Chaque champ représente une donnée en particulier. En plus, chaque table contient un certain nombre de lignes, appelées les entrées, ou les records en anglais. En général, bien que ce ne soit pas obligatoirement le cas, chaque ligne est identifiée par un ID (pour IDentificateur) unique. Il peut s'agir par exemple d'un numéro/ID de client, de job, de facture, etc. C'est en général à l'aide de ces identificateurs que l'on définit les liens qui relient chaque table.
Le langage SQL n'est pas sensible à la case. Cependant, par convention, on met généralement les mots-clés du langage en majuscules.
Les quatre commandes pour agir sur les données
Il existe quatre principales commandes pour agir sur les données. Une commande pour ajouter des données à une table (INSERT), une commande pour supprimer des données d'une table (DELETE), une commande pour modifier les données (UPDATE), et une commande pour rechercher des données (SELECT).
INSERT
Cette commande permet d'ajouter une entrée à une table précise. La syntaxe recommandée pour cette commande est la suivante :
INSERT (champ1,champ2,...,champN) VALUES (valeur1,valeur2,...,valeurN) INTO nomDeTable
Le premier mot est le nom de la commande. On a ensuite la liste des champs de la table dans laquelle on veut ajouter une entrée. Le mot-clé VALUES> spécifie que la liste suivante est la liste des valeurs. La valeur valeur1 sera insérée dans le champ champ1 et ainsi de suite. Le mot-clé INTO précise que le mot suivant est le nom de la table.
Par exemple, la requête suivante :
INSERT (eta,gamma,t,phi,xsi,seed) VALUES (1.0,0.0,0.01,60.0,0.0,17) INTO paramSimulation
Créera une entrée dans la table paramSimulation, en mettant la valeur 1.0 dans le champ eta, la valeur 0.0 dans le champ gamma, la valeur 0.01 dans le champ t, la valeur 60.0 dans le champ phi, la valeur 0.0 dans le champ xsi et la valeur 17 dans le champ seed.
Vous noterez que cette requête n'insérait pas de valeurs dans le champ identificateur de la table. Souvent, le champ identificateur d'une table est un numéro généré automatiquement. Dans ce cas, il sera retourné par la commande INSERT et vous pourrez donc le récupérer pour l'utiliser ultérieurement dans votre programme.
DELETE
Cette commande permet de supprimer une ou plusieurs entrées dans une table précise. Sa syntaxe est la suivante :
DELETE FROM nomTable [WHERE <criteres>]
Si vous exécutez cette commande sans inclure de clause WHERE, cela supprimera TOUS les champs de la table. Cependant, si vous incluez une clause WHERE, vous pouvez supprimer une rangée particulière ou un groupe de rangées de la table. Pour plus d'informations sur la clause WHERE, voir plus bas. La valeur de retour de cette commande est le nombre d'entrées supprimées de la table. Voici quelques exemples :
Cette commande supprimera les entrées dans la table paramSimulation pour lesquelles jobId est égal à 1493 :
DELETE FROM paramSimulation WHERE jobId=1493
Cette commande supprimera les entrées dans la table paramSimulation pour lesquelles le champ gamma est entre 0.0 et 0.4 :
DELETE FROM paramSimulation WHERE gamma BETWEEN 0.0 AND 0.4
Cette commande supprimera les entrées dans la table modesCollectifs pour lesquelles le champ parcours est parmi les valeurs (-1,0,3) :
DELETE FROM modesCollectifs WHERE parcours IN (-1,0,3)
UPDATE
Cette commande permet de modifier une entrée existante dans une table. Sa syntaxe est la suivante :
UPDATE nomTable SET champ1=valeur1 [, champ2=valeur2, ... champN=valeurN] [WHERE <criteres>]
La valeur de retour de la commande est le nombre d'entrées modifiées. Voici quelques exemples d'utilisation :
Cette commande modifiera toutes les entrées de la table paramSimulation pour lesquelles le champ seed vaut 17, et mettra la valeur de ce champ à 24 :
UPDATE paramSimulation SET seed=24 WHERE seed=17
Cette commande modifiera toutes entrées de la table modesCollectifs et mettra la valeur -1 dans le champ parcours :
UPDATE modesCollectifs SET parcours=-1
SELECT
Cette commande permet de faire une recherche et de sélectionner un ensemble de données dans la base de données. Sa syntaxe la plus simple est la suivante :
SELECT champ1 [, champ2, ..., champN] FROM nomTable [WHERE <criteres>] [ORDER BY <criteres de tri>]
Cette commande retourne un tableau de données contenant N colonnes et toutes les rangées qui répondaient aux critères du WHERE. Voici quelques exemples d'utilisation de cette commande :
Cette commande retourne les champs seed, nu et gamma pour toutes les entrées de la table paramSimulation pour lesquelles la valeur de gamma est entre 0.0 et 0.01 :
SELECT seed, nu, gamma FROM paramSimulation WHERE gamma BETWEEN 0.0 AND 0.01
Cette commande retourne les champs seed, t et d pour toutes les entrées de la table paramSimulation pour lesquelles la valeur de d est plus grande ou égale à 1.0 :
SELECT seed, t, d FROM paramSimulation WHERE d >= 1.0
Si vous voulez sélectionner tous les champs d'une table, vous pouvez aussi utiliser l'étoile (*) ainsi :
SELECT * FROM paramSimulation [WHERE <criteres>]
Cette pratique n'est cependant pas recommandée, car les champs retournés dépendent de la structure de la table en question. Donc, si votre programme assume qu'il reçoit un nombre N de champs et que la table de la base de données est modifiée, il pourrait en recevoir plus ou moins que prévus, ou bien les recevoir dans le mauvais ordre.
Utiliser plusieurs tables dans un SELECT
Il est possible de joindre plusieurs tables à l'intérieur d'un même SELECT. Ceci se fait par l'intermédiaire de la clause JOIN :
SELECT <liste de champs> FROM table1 [LEFT OUTER | RIGHT OUTER | OUTER | INNER] JOIN table2 ON table1.champ1 = table2.champ2 [WHERE <criteres>]
Cette requete retournerait un tableau contenant tous les champs des tables table1 et table2 pour lesquels le champ champ1 de la table table1 est égal au champ champ2 de la table table2 et qui répondent aux critères de la clause WHERE.
Les quatres types de JOIN agissent ainsi :
- INNER : retourne des valeurs pour chaque rangée dans la table table1 à laquelle correspond une rangée dans la table table2
- LEFT OUTER : retourne des valeurs pour chaque rangée dans la table à gauche (table1), même si aucune rangée de la table à droite n'y correspond. Si la requête contient des champs de la table à droite, la valeur null sera mise dans ces champs.
- RIGHT OUTER : retourne des valeurs pour chaque rangée dans la table à droite (table2), même si aucune rangée de la table à gauche n'y correspond.
- OUTER : retourne des valeurs pour chaque rangée dans la table à gauche et dans celle à droite, même s'il n'y a aucune correspondance entre les rangées.
En général, on utilisera surtout les INNER JOIN, car on désire généralement une correspondance un à un entre les deux tables.
Il est aussi possible de donner des alias aux tables, pour raccourcir la requête SQL. Par exemple :
SELECT gamma, eta FROM paramSimulation p INNER JOIN
results r ON p.jobId = r.jobId WHERE d <= 3.0
Il n'est pas nécessaire de spécifier à quelle table appartient un champ si les autres tables impliquées dans la requête ne contiennent pas de champ du même nom. Dans le cas contraire, il faut spécifier le nom de la table avant le nom du champ :
SELECT p.jobId, paramSimulation.gamma, eta, E FROM paramSimulation p INNER JOIN results r ON p.jobId = r.jobId WHERE seed BETWEEN 1 AND 20
Il est bien sûr possible de joindre plus de deux tables. Il s'agit d'imbriquer les JOIN :
SELECT p.jobId, b.nomProg, gamma, eta, E FROM (batch b INNER JOIN paramSimulation p ON b.batchId = p.batchId) INNER JOIN results r ON p.jobId = r.jobId WHERE batch.login = 'mboisson'
SELECT imbriqués
Il est possible d'imbriquer les SELECT de manière à aller chercher une valeur précise dans une table qui n'est pas incluse dans la requête de base. Par exemple, la requête suivante :
SELECT p.jobId, (SELECT COUNT(*) FROM modesCollectifs WHERE modesCollectifs.jobId = p.jobId) AS numModes FROM paramSimulation p
Retournerait le jobId et le nombre d'entrées correspondantes dans la table modesCollectifs, et mettrait ce nombre dans un champ nommé numModes. On a utilisé ici la fonction COUNT(), qui est une fonction regroupante.
Fonctions regroupantes
Une fonction regroupante est une fonction qui retourne une seule valeur pour toutes les rangées retournées par le SELECT. Le SELECT imbriqué ci-dessus retourne donc une seule valeur pour chaque jobId différent. Par exemple, pour avoir le nombre d'entrées dans une table correspondant à certains critères, on peut exécuter la requête :
SELECT COUNT(*) FROM nomTable [WHERE <criteres>]
Les fonctions regroupantes MAX() et MIN() sont aussi utilisées fréquemment. La requête suivante retournerait la valeur du plus grand jobId contenu dans la table paramSimulation :
SELECT MAX(jobId) FROM paramSimulation
La clause GROUP BY
Si on voulait récupérer un autre champ en plus du résultat d'une fonction regroupante, il faudrait utiliser la clause GROUP BY. Par exemple, la requête suivante retournerait le nombre d'entrées dans la table paramSimulation pour chaque valeur du champ seed :
SELECT COUNT(*), seed FROM paramSimulation GROUP BY seed
On ne peut récupérer la valeur d'un champ X si on utilise une fonction regroupante sur le champ Y à moins d'inclure le champ X dans la clause GROUP BY.
La clause WHERE
La clause WHERE peut être utilisée dans les commandes SELECT, UPDATE, DELETE. Il est possible d'utiliser tous les opérateurs de comparaison standards :
- champ = val, pour l'égalité
- champ <> val, pour l'inégalité
- champ < val, pour plus petit
- champ <= val, pour plus petit ou égal
- champ > val, pour plus grand
- champ >= val, pour plus grand ou égal
En plus, il est possible d'utiliser les opérateurs BETWEEN, IN :
- champ BETWEEN val1 AND val2, pour que le champ soit entre val1 et val2
- champ IN (val1,val2,val3,...,valN), pour que le champ soit dans la liste spécifiée
Avec l'opérateur IN, il est possible d'utiliser un SELECT imbriqué pour retourner une liste de valeurs. Par exemple, la requête suivante retournerait toutes les rangées de la table modesCollectifs pour lesquels les jobId sont parmi les jobId de la table paramSimulation pour lesquels la valeur du champ seed est 19 :
SELECT * FROM modesCollectifs WHERE jobId IN (SELECT jobId FROM paramSimulation WHERE seed = 19)
Pour les recherches sur les champs de type chaîne de caractères, il y a l'opérateur LIKE :
- champ LIKE 'b?ah%'
Avec l'opérateur LIKE, le caractère % joue le rôle du *, c'est à dire qu'il recherche n'importe quelle chaîne de caractère. Le caractère ? recherche n'importe caractère individuel.
La clause ORDER BY
La clause SORT BY permet de trier le tableau retourné par une commande SELECT. Les critères de tri doivent être séparés par des virgules. Par exemple, la requête suivante retournerait le champ jobId, eta, d et seed triés selon le champ seed ascendant et ensuite par le champ d descendant :
SELECT jobId, eta, d, seed FROM paramSimulations ORDER BY seed ASC, d DESC
Auteur: Maxime Boissonneault
8 décembre 2004