samedi 22 mars 2014

12 - Insertion de données

0 commentaires


Ce chapitre est consacré à l'insertion de données dans une table. Rien de bien compliqué, mais c'est évidemment crucial. En effet, que serait une base de données sans données ?
Nous verrons entre autres :
  • comment insérer une ligne dans une table ;
  • comment insérer plusieurs lignes dans une table ;
  • comment exécuter des requêtes SQL écrites dans un fichier (requêtes d'insertion ou autres) ;
  • comment insérer dans une table des lignes définies dans un fichier de format particulier.

Et pour terminer, nous peuplerons notre table Animal d'une soixantaine de petites bestioles sur lesquelles nous pourrons tester toutes sortes de tortures requêtes dans la suite de ce tutoriel. 
Deux possibilités s'offrent à nous lorsque l'on veut insérer une ligne dans une table : soit donner une valeur pour chaque colonne de la ligne, soit ne donner les valeurs que de certaines colonnes, auquel cas il faut bien sûr préciser de quelles colonnes il s'agit.

Insertion sans préciser les colonnes

Je rappelle pour les distraits que notre table Animal est composée de six colonnes : idespecesexe,date_naissancenom et commentaires.
Voici donc la syntaxe à utiliser pour insérer une ligne dans Animal, sans renseigner les colonnes pour lesquelles on donne une valeur (implicitement, MySQL considère que l'on donne une valeur pour chaque colonne de la table).
1INSERT INTO Animal 
2VALUES (1'chien''M''2010-04-05 13:43:00''Rox''Mordille beaucoup');
Deuxième exemple : cette fois-ci, on ne connaît pas le sexe et on n'a aucun commentaire à faire sur la bestiole :
1INSERT INTO Animal 
2VALUES (2'chat'NULL'2010-03-24 02:23:00''Roucky'NULL);
Troisième et dernier exemple : on donne NULL comme valeur d'id, ce qui en principe est impossible puisque id est défini comme NOT NULL et comme clé primaire. Cependant, l'auto-incrémentation fait que MySQL va calculer tout seul comme un grand quel id il faut donner à la ligne (ici : 3).
1INSERT INTO Animal 
2VALUES (NULL , 'chat''F''2010-09-13 15:02:00''Schtroumpfette'NULL);
Vous avez maintenant trois animaux dans votre table :
Id
Espèce
Sexe
Date de naissance
Nom
Commentaires
1
chien
M
2010-04-05 13:43:00
Rox
Mordille beaucoup
2
chat
NULL
2010-03-24 02:23:00
Roucky
NULL
3
chat
F
2010-09-13 15:02:00
Schtroumpfette
NULL
Pour vérifier, vous pouvez utiliser la requête suivante :
1SELECT * FROM Animal;
Deux choses importantes à retenir ici.
  • id est un nombre, on ne met donc pas de guillemets autour. Par contre, l'espèce, le nom, la date de naissance et le sexe sont donnés sous forme de chaînes de caractères. Les guillemets sont donc indispensables. Quant à NULL, il s'agit d'un marqueur SQL qui, je rappelle, signifie "pas de valeur". Pas de guillemets donc.
  • Les valeurs des colonnes sont données dans le bon ordre (donc dans l'ordre donné lors de la création de la table). C'est indispensable évidemment. Si vous échangez le nom et l'espèce par exemple, comment MySQL pourrait-il le savoir ?

Insertion en précisant les colonnes

Dans la requête, nous allons donc écrire explicitement à quelle(s) colonne(s) nous donnons une valeur. Ceci va permettre deux choses.
  • On ne doit plus donner les valeurs dans l'ordre de création des colonnes, mais dans l'ordre précisé par la requête.
  • On n'est plus obligé de donner une valeur à chaque colonne ; plus besoin de NULL lorsqu'on n'a pas de valeur à mettre.
Quelques exemples :
1INSERT INTO Animal (especesexedate_naissance) 
2    VALUES ('tortue''F''2009-08-03 05:12:00');
3INSERT INTO Animal (nomcommentairesdate_naissanceespece) 
4    VALUES ('Choupi''Né sans oreille gauche''2010-10-03 16:44:00''chat');
5INSERT INTO Animal (especedate_naissancecommentairesnomsexe) 
6    VALUES ('tortue''2009-06-13 08:17:00''Carapace bizarre''Bobosse''F');
Ce qui vous donne trois animaux supplémentaires (donc six en tout, il faut suivre !)

Insertion multiple

Si vous avez plusieurs lignes à introduire, il est possible de le faire en une seule requête de la manière suivante :
1INSERT INTO Animal (especesexedate_naissancenom) 
2VALUES ('chien''F''2008-12-06 05:18:00''Caroline'),
3        ('chat''M''2008-09-11 15:38:00''Bagherra'),
4        ('tortue'NULL'2010-08-23 05:18:00'NULL);
Bien entendu, vous êtes alors obligés de préciser les mêmes colonnes pour chaque entrée, quitte à mettre NULL pour certaines. Mais avouez que ça fait quand même moins à écrire !
MySQL propose une syntaxe alternative à INSERT INTO ... VALUES ... pour insérer des données dans une table.
1INSERT INTO Animal 
2SET nom='Bobo'espece='chien'sexe='M'date_naissance='2010-07-21 15:41:00';
Cette syntaxe présente deux avantages.
  • Le fait d'avoir l'un à côté de l'autre la colonne et la valeur qu'on lui attribue (nom = 'Bobo') rend la syntaxe plus lisible et plus facile à manipuler. En effet, ici il n'y a que six colonnes, mais imaginez une table avec 20, voire 100 colonnes. Difficile d'être sûrs que l'ordre dans lequel on a déclaré les colonnes est bien le même que l'ordre des valeurs qu'on leur donne…
  • Elle est très semblable à la syntaxe de UPDATE, que nous verrons plus tard et qui permet de modifier des données existantes. C'est donc moins de choses à retenir (mais bon, une requête de plus ou de moins, ce n'est pas non plus énorme…)


En effet, cette syntaxe présente deux défauts majeurs.
  • Elle est propre à MySQL. Ce n'est pas du SQL pur. De ce fait, si vous décidez un jour de migrer votre base vers un autre SGBDR, vous devrez réécrire toutes les requêtes INSERT utilisant cette syntaxe.
  • Elle ne permet pas l'insertion multiple.




  • Maintenant que vous savez insérer des données, je vous propose de remplir un peu cette table, histoire qu'on puisse s'amuser par la suite.
    Rassurez-vous, je ne vais pas vous demander d'inventer cinquante bestioles et d'écrire une à une les requêtes permettant de les insérer. Je vous ai prémâché le boulot. De plus, ça nous permettra d'avoir, vous et moi, la même chose dans notre base. Ce sera ainsi plus facile de vérifier que vos requêtes font bien ce qu'elles doivent faire.
    Et pour éviter d'écrire vous-mêmes toutes les requêtes d'insertion, nous allons donc voir comment on peut utiliser un fichier texte pour interagir avec notre base de données.

    Exécuter des commandes SQL à partir d'un fichier

    Écrire toutes les commandes à la main dans la console, ça peut vite devenir pénible. Quand c'est une petite requête, pas de problème. Mais quand vous avez une longue requête, ou beaucoup de requêtes à faire, ça peut être assez long.
    Une solution sympathique est d'écrire les requêtes dans un fichier texte, puis de dire à MySQL d'exécuter les requêtes contenues dans ce fichier. Et pour lui dire ça, c'est facile :
    1SOURCE monFichier.sql;
    Ou
    1\. monFichier.sql;
    Ces deux commandes sont équivalentes et vont exécuter le fichier monFichier.sql. Il n'est pas indispensable de lui donner l'extension .sql, mais je préfère le faire pour repérer mes fichiers SQL directement. De plus, si vous utilisez un éditeur de texte un peu plus évolué que le bloc-note (ou textEdit sur Mac), cela colorera votre code SQL, ce qui vous facilitera aussi les choses.
    Attention : si vous ne lui indiquez pas le chemin, MySQL va aller chercher votre fichier dans le dossier où vous étiez lors de votre connexion.
    Exemple : on donne le chemin complet vers le fichier
    1SOURCE C:\Document and Settings\dossierX\monFichier.sql;

    Insérer des données à partir d'un fichier formaté

    Par fichier formaté, j'entends un fichier qui suit certaines règles de format. Un exemple typique serait les fichiers .csv. Ces fichiers contiennent un certain nombre de données et sont organisés en tables. Chaque ligne correspond à une entrée, et les colonnes de la table sont séparées par un caractère défini (souvent une virgule ou un point-virgule). Ceci par exemple, est un format csv :
    1nom;prenom;date_naissance
    2Charles;Myeur;1994-12-30
    3Bruno;Debor;1978-05-12
    4Mireille;Franelli;1990-08-23
    Ce type de fichier est facile à produire (et à lire) avec un logiciel de type tableur (Microsoft Excel, ExcelViewer, Numbers…). La bonne nouvelle est qu'il est aussi possible de lire ce type de fichier avec MySQL, afin de remplir une table avec les données contenues dans le fichier.
    La commande SQL permettant cela est LOAD DATA INFILE, dont voici la syntaxe :
    1LOAD DATA [LOCALINFILE 'nom_fichier'
    2INTO TABLE nom_table
    3[FIELDS
    4    [TERMINATED BY '\t']
    5    [ENCLOSED BY '']
    6    [ESCAPED BY '\\' ]
    7]
    8[LINES 
    9    [STARTING BY '']    
    10    [TERMINATED BY '\n']
    11]
    12[IGNORE nombre LINES]
    13[(nom_colonne,...)];
    Le mot-clé LOCAL sert à spécifier si le fichier se trouve côté client (dans ce cas, on utilise LOCAL) ou côté serveur (auquel cas, on ne met pas LOCAL dans la commande). Si le fichier se trouve du côté serveur, il est obligatoire, pour des raisons de sécurité, qu'il soit dans le répertoire de la base de données, c'est-à-dire dans le répertoire créé par MySQL à la création de la base de données, et qui contient les fichiers dans lesquels sont stockées les données de la base. Pour ma part, j'utiliserai toujours LOCAL, afin de pouvoir mettre simplement mes fichiers dans mon dossier de travail.
    Les clauses FIELDS et LINES permettent de définir le format de fichier utilisé. FIELDS se rapporte aux colonnes, et LINES aux lignes (si si ^^ ). Ces deux clauses sont facultatives. Les valeurs que j'ai mises ci-dessus sont les valeurs par défaut.
    Si vous précisez une clause FIELDS, il faut lui donner au moins une des trois "sous-clauses".
    • TERMINATED BY, qui définit le caractère séparant les colonnes, entre guillemets bien sûr. ' 'correspond à une tabulation. C'est le caractère par défaut.
    • ENCLOSED BY, qui définit le caractère entourant les valeurs dans chaque colonne (vide par défaut).
    • ESCAPED BY, qui définit le caractère d'échappement pour les caractères spéciaux. Si par exemple vous définissez vos valeurs comme entourées d'apostrophes, mais que certaines valeurs contiennent des apostrophes, il faut échapper ces apostrophes "internes" afin qu'elles ne soient pas considérées comme un début ou une fin de valeur. Par défaut, il s'agit du \ habituel. Remarquez qu'il faut lui-même l'échapper dans la clause.
    De même pour LINES, si vous l'utilisez, il faut lui donner une ou deux sous-clauses.
    • STARTING BY, qui définit le caractère de début de ligne (vide par défaut).
    • TERMINATED BY, qui définit le caractère de fin de ligne (' ' par défaut, mais attention : les fichiers générés sous Windows ont souvent ' ' comme caractère de fin de ligne).
    La clause IGNORE nombre LINES permet… d'ignorer un certain nombre de lignes. Par exemple, si la première ligne de votre fichier contient les noms des colonnes, vous ne voulez pas l'insérer dans votre table. Il suffit alors d'utiliser IGNORE 1 LINES.
    Enfin, vous pouvez préciser le nom des colonnes présentes dans votre fichier. Attention évidemment à ce que les colonnes absentes acceptent NULL ou soient auto-incrémentées.
    Si je reprends mon exemple, en imaginant que nous ayons une table Personne contenant les colonnesid (clé primaire auto-incrémentée), nom, prenom, date_naissance et adresse (qui peut être NULL).
    1nom;prenom;date_naissance
    2Charles;Myeur;1994-12-30
    3Bruno;Debor;1978-05-12
    4Mireille;Franelli;1990-08-23
    Si ce fichier est enregistré sous le nom personne.csv, il vous suffit d'exécuter la commande suivante pour enregistrer ces trois lignes dans la table Personne, en spécifiant si nécessaire le chemin complet vers personne.csv :
    1LOAD DATA LOCAL INFILE 'personne.csv'
    2INTO TABLE Personne
    3FIELDS TERMINATED BY ';'
    4LINES TERMINATED BY '\n' -- ou '\r\n' selon l'ordinateur et le programme utilisés pour créer le fichier
    5IGNORE 1 LINES
    6(nom,prenom,date_naissance);

Leave a Reply