INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] Nom_table [(Nom_col,...)]
VALUES (expression,...),(...),...
ou INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] Nom_table [(Nom_col,...)]
SELECT ...
ou INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] Nom_table
SET Nom_col=expression, Nom_col=expression, ...
INSERT
insère une nouvelle ligne dans une table existante.. La forme de INSERT ... VALUES
est basée sur des colonnes explicitement précisée. forme de INSERT ... SELECT
insère des données depuis une autre table. La forme de INSERT ... VALUES
avec plusieurs valeurs est acceptée MySQL à partir de la version 3.22.5 . La syntaxe Nom_col=expression
est accepté par MySQL à partir de la version 3.22.10.
Nom_table
est le nom de la table dans laquelle les lignes vont être insérée. La liste de nom de colonne ou la clause SET
indique quelles colonnes vont être assignées.
- Si aucun nom de colonne n'est précisé dans la commande,
INSERT ... VALUES
or INSERT ... SELECT
, alors des valeurs doivent être fournies pour toutes les colonnes dans la liste de VALUES()
. Pour connaître l'ordre des colonnes, il faut utiliser la commande DESCRIBE Nom_table
.
- Toute colonne qui n'a pas de valeur explicitement fournie est mise à sa valeur par défaut. Par exemple, il est possible de fournir une liste de colonne en omettant certains noms : les valeurs de ces colonnes seront les valeurs par défaut. Pour avoir les détails sur les valeurs par défaut,
CREATE TABLE
.
- Une
expression
peut faire référence à n'importe quelle colonne déjà nommée dans la liste des colonnes. Par exemple :
mysql> INSERT INTO Nom_table (col1,col2) VALUES(15,col1*2);
Mais pas ceci :
mysql> INSERT INTO Nom_table (col1,col2) VALUES(col2*2,15);
- L'option
LOW_PRIORITY
permet de différer une exécution jusqu'à ce qu'il n'y ait plus de client qui lisent la table.
- L'option permet, lors de l'insertion dans une table qui a une colonne de type
PRIMARY
or UNIQUE
, de ne pas renvoyer d'erreur si une insertion essaie de doubler une clé déjà existante. Si cette option n'est pas précisée, l'insertion est annulée à partir de la ligne erronée. Le nombre de ligne correctement insérées est accessible avec mysql_info()
.
- Si MySQL a été configuré avec l'option
DONT_USE_DEFAULT_FIELDS
, une commande INSERT
devra avoir la liste complète des colonnes qui requière une valeur non-NULL.
- Les conditions suivantes s'appliquent aux commandes de type
INSERT INTO ... SELECT
- La requête ne peut pas contenir de clause
ORDER BY
- La table cible de l'insertion ne peut pas apparaître dans la clause
FROM
du SELECT
, car la norme ANSI SQL l'interdit (en effet, le SELECT
pourrait trouver des lignes qui viennent juste d'être insérée. Utiliser des sous-selections serait encore pire).
Les colonnes de type AUTO_INCREMENT
fonctionnent de la même façon.
Lors de l'utilisation de INSERT ... SELECT
ou INSERT ... VALUES
avec des listes de plusieurs lignes, la fonction mysql_info()
permet d'obtenir des informations sur la requête. Le format de la réponse est comme suite :
Records: 100 Duplicates: 0 Warnings: 0
Duplicates
indique le nombre de lignes qui n'a pas pus être insérées car elles tentaient de doubler une clé primaire.. Warnings
indique le nombre d'insertions qui ont générer une erreur lors de l'insertion. Warnings
surviennent lorsqu'il y a une tentative:
- Insertion d'une valeur
NULL
dans une colonne déclarée NOT NULL
.
- Assignation d'une valeur numérique qui est hors de l'intervalle de validité de la colonne. Cette valeur est ramenée à la valeur valide la plus proche.
- Assignation d'une valeur telle que
'10.34 a'
. Dans ce cas, les résidus inutiles sont éliminés. Si la valeur ne peut pas être interprétée, la valeur 0
est assignée à la place.
- Insertion d'une chaîne dans une colonne de type
CHAR
, VARCHAR
, TEXT
ou BLOB
qui excède la longueur maximale. La valeur est alors tronquée à la taille maximale de la colonne.
- Insertion d'une valeur invalide dans une date ou heure. La valeur est alors fixée au ``zéro'' du type de la colonne.
L'option DELAYED
pour la commande INSERT
est une caractéristique MySQL qui est très utile lorsque les clients ne peuvent pas attendre la fin de l'insertion. C'est utilisé habituellement par MySQL pour remplir des historiques, et que périodiquement, une longue commande SELECT
est effectuée. DELAYED
a été introduit à partir de MySQL 3.22.15. C'est une extension MySQL à la norme ANSI SQL92.
Un autre avantage majeur de l'utilisation de la commande INSERT DELAYED
est que les insertions sont regroupées et traitées en même temps. C'est une manière plus rapide que d'effectuer autant d'insertions unitaires.
Il faut noter que les insertions en attente sont gardées en mémoire vive, jusqu'à ce qu'elles soient insérées dans la table. Cela signifie que si le processus mysqld
est brutalement interrompu (kill -9
) ou si mysqld
se termine inopinément, les lignes ne seront pas écrites sur le disque, et ainsi perdues !
Les événements suivants surviennent lors de l'utilisation de l'option DELAYED
des commandes INSERT
ou REPLACE
. Dans la description qui suit, le ``thread'' est le thread qui a recu la commande INSERT DELAYED
et ``handler'' est le thread qui va gérer les INSERT DELAYED
pour une table particulière.
- Quand un thread exécute la commande
DELAYED
pour une table, le thread handler est crée pour gérer toutes les commandes DELAYED
pour la table, si un tel thread n'existe pas.
- Le thread vérifie si le handler a bien posé un verrou
DELAYED
, et si non, il lui dit de le faire. Le verrou DELAYED
peut être obtenu même si d'autres threads ont déjà obtenu un verrou de READ
ou WRITE
sur la table. Cependant, le handler va attendre que tous les verrous ALTER TABLE
ou FLUSH TABLES
soient libérés, afin de s'assurer que la table est bien à jour.
- Le thread exécute l'insertion mais, au lieu d'écrire la ligne dans la table, il transmet une copie de la ligne finale au handler, qui l'ajoute dans la queue d'attente. Toutes les erreurs d'insertions sont notées par le thread, et rapportées au client.
- Le client ne reçoit pas le nombre de doublons, ou la valeur d'
AUTO_INCREMENT
qu'il pourrait attendre, car ces informations ne sont connues qu'après l'insertion proprement dite. De la même façon, mysql_info()
risque de retourner des informations incohérentes.
- L'historique de mise à jour est modifié par le handler quand la ligne est effectivement insérée dans la table. Si il y a plusieurs lignes insérées simultanément, l'historique de mise à jour est modifié lors de l'insertion de la première ligne.
- Après chaque bloc de
delayed_insert_limit
lignes écrites, le handler vérifie si il n'y a pas de commande SELECT
en attente. Si c'est le cas, il s'arrête, et l'exécute avant de continuer.
- Quand le handler n'a plus de ligne dans la queue, la table est déverrouillée. Si aucune autre commandes
INSERT DELAYED
n'est reçue dans un délai de delayed_insert_timeout
secondes, le handler se termine.
- Si il reste plus de
delayed_queue_size
lignes en attente d'insertion, le thread attend jusqu'à ce qu'il y ait de la place dans la queue. Ce permet de contrôler la quantité de mémoire utilisé pour les queues d'attentes.
- Le handler apparaîtra dans la liste des processus MySQL avec le mot
delayed_insert
dans la colonne de Command
. Il sera automatiquement effacé lors d'une commande FLUSH TABLES
ou KILL thread_id
. Cependant, il enregistrera les lignes dans la table avant de quitter. Durant cette période, le handler n'acceptera plus aucune nouvelle commande INSERT
d'un autre thread. Si une nouvelle commande an INSERT DELAYED
est éxécutée, un nouveau handler sera créé.
- Il faut bien noter que les commandes
INSERT DELAYED
ont une priorité supérieure aux commandes INSERT
, si un handler est déjà en fonctionnement. Toutes les autres commandes doivent attendre que la queue d'attente du handler soit vide (même par un kill).
- Les statuts suivants fournissent des informations sur l'état des commandes
INSERT DELAYED :
Ces variables sont accessibles avec la commande SHOW STATUS
ou, en ligne, avec mysqladmin extended-status
.