621 votes

Est-il possible d'insérer plusieurs lignes à la fois dans une base de données SQLite ?

Dans MySQL, vous pouvez insérer plusieurs lignes comme ceci :

INSERT INTO 'tablename' ('column1', 'column2') VALUES
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2');

Cependant, j'obtiens une erreur lorsque j'essaie de faire quelque chose comme ceci. Est-il possible d'insérer plusieurs lignes à la fois dans une base de données SQLite ? Quelle est la syntaxe pour le faire ?

31 votes

Il ne s'agit pas d'un doublon, car cette question porte sur SQLite en particulier, et non sur SQL en général (bien que certaines des réponses à cette question soient utiles pour celle-ci).

6 votes

Sur les encarts en vrac : stackoverflow.com/questions/1711631/

6 votes

La question est de savoir pourquoi vous devriez le faire. Étant donné que SQlite est en cours de traitement sur la même machine et que vous pouvez regrouper plusieurs insertions dans une transaction, je n'en vois pas la nécessité ?

664voto

fearless_fool Points 9190

Mise à jour

Como BrianCampbell souligne ici , SQLite 3.7.11 et plus supporte maintenant la syntaxe plus simple de l'article original . Cependant, l'approche présentée est toujours appropriée si vous souhaitez une compatibilité maximale entre les bases de données existantes.

première réponse

Si j'avais des privilèges, je bousculerais réponse de la rivière : Vous peut insérer plusieurs lignes dans SQLite, il suffit de syntaxe différente . Pour être parfaitement clair, l'exemple MySQL du PO :

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2');

Cela peut être reformulé en SQLite comme suit :

     INSERT INTO 'tablename'
          SELECT 'data1' AS 'column1', 'data2' AS 'column2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'

une note sur les performances

J'ai initialement utilisé cette technique pour charger efficacement de grands ensembles de données à partir de Ruby on Rails. Cependant , comme le souligne Jaime Cook il n'est pas évident que ce soit un emballage individuel plus rapide. INSERTs au cours d'une même transaction :

BEGIN TRANSACTION;
INSERT INTO 'tablename' table VALUES ('data1', 'data2');
INSERT INTO 'tablename' table VALUES ('data3', 'data4');
...
COMMIT;

Si l'efficacité est votre objectif, vous devriez d'abord essayer ceci.

une note sur UNION vs UNION ALL

Comme plusieurs personnes l'ont fait remarquer, si vous utilisez UNION ALL (comme illustré ci-dessus), toutes les lignes seront insérées, donc dans ce cas, vous obtiendrez quatre lignes de data1, data2 . Si vous omettez le ALL les lignes en double seront éliminées (et l'opération sera sans doute un peu plus lente). Nous utilisons UNION ALL car cela correspond mieux à la sémantique de l'article original.

en clôture

P.S. : S'il vous plaît +1 réponse de la rivière car il a présenté la solution en premier.

104 votes

Par ailleurs, sqlite ne semble supporter que jusqu'à 500 sélections d'union par requête. Si vous essayez d'introduire plus de données que cela, vous devrez les diviser en blocs de 500 éléments ( sqlite.org/limites.html )

0 votes

Je ne pense pas qu'il y ait un tel gain de performance. Les transactions de SQLite sont TRÈS rapides avec les insertions.

4 votes

Je suis d'accord : SQLite n'est pas le goulot d'étranglement, c'est l'overhead des transactions ORM individuelles (dans mon cas, Ruby On Rails). Donc c'est toujours une grande victoire.

590voto

andy Points 3414

Oui, c'est possible, mais pas avec les valeurs d'insertion habituelles séparées par des virgules.

Essayez ceci...

insert into myTable (col1,col2) 
     select aValue as col1,anotherValue as col2 
     union select moreValue,evenMoreValue 
     union...

Oui, c'est un peu laid, mais il est assez facile d'automatiser la génération de l'instruction à partir d'un ensemble de valeurs. De plus, il semble que vous n'ayez besoin de déclarer les noms des colonnes que dans la première sélection.

37 votes

Veuillez utiliser UNION ALL pas UNION . Sauf si vous voulez supprimer les doublons.

4 votes

Si vous voulez que les ID s'incrémentent automatiquement, donnez-leur une valeur NULL.

255voto

Brian Campbell Points 101107

Oui, à partir de SQLite 3.7.11 ceci est supporté par SQLite. De la Documentation SQLite :

SQLite INSERT statement syntax

(lorsque cette réponse a été écrite à l'origine, ceci n'était pas pris en charge)

Pour la compatibilité avec les anciennes versions de SQLite, vous pouvez utiliser l'astuce suggérée par andy y fearless_fool en utilisant UNION mais pour 3.7.11 et les versions ultérieures, la syntaxe plus simple décrite ici devrait être préférée.

3 votes

Je dirais que le diagramme permet plusieurs rangées, car il y a une boucle fermée avec une virgule à l'extérieur des parenthèses après VALUES .

0 votes

@JohannesGerer Ils ont mis à jour cette image depuis que je l'ai intégrée. Vous pouvez voir le diagramme au moment où je l'ai intégré à l'adresse suivante Archives Internet . En fait, c'était il y a seulement deux mois qu'ils ont ajouté la prise en charge de plusieurs lignes dans une insertion, et il y a juste deux jours qu'ils ont publié une version avec ce changement. Je vais mettre à jour ma réponse en conséquence.

2 votes

@Brian, pourriez-vous citer le texte de la documentation SQLite, qui indique que cette IS possible ? J'ai relu 3 fois la documentation sur l'insertion et je n'ai rien trouvé sur l'insertion de plusieurs lignes, mais seulement cette image (et rien sur la virgule dans le texte). VALUES (...), (...) ) :(

69voto

Jamie Cook Points 1669

J'ai écrit du code ruby pour générer une insertion unique de 500 éléments sur plusieurs lignes à partir d'une série d'instructions d'insertion, ce qui était considérablement plus rapide que d'exécuter les insertions individuelles. J'ai ensuite essayé de regrouper les insertions multiples en une seule transaction et j'ai constaté que je pouvais obtenir le même type de vitesse avec beaucoup moins de code.

BEGIN TRANSACTION;
INSERT INTO table VALUES (1,1,1,1);
INSERT INTO table VALUES (2,2,2,2);
...
COMMIT;

1 votes

Mais cela n'a pas fonctionné dans le code, alors que cela fonctionne directement dans le gestionnaire SQLite. Dans le code, il n'insère que la première ligne :(

5 votes

J'utilise ce style d'insertion dans mon code et cela fonctionne parfaitement. Vous devez seulement vous assurer que vous soumettez TOUT le SQL en une seule fois. Cela m'a permis de gagner énormément de temps, mais je suis curieux de savoir si la réponse acceptée est plus rapide ou plus lente que cela ?

0 votes

Cette approche s'adapte très bien à la modification de plusieurs tables dans une seule transaction, ce que je fais souvent lorsque je charge une base de données par lots.

42voto

typeseven Points 612

Selon cette page il n'est pas pris en charge :

  • 2007-12-03 : L'INSERT multi-lignes, aussi appelé INSERT composé, n'est pas supporté.
  INSERT INTO table (col1, col2) VALUES 
      ('row1col1', 'row1col2'), ('row2col1', 'row2col2'), ...

En fait, selon la norme SQL92, une expression VALUES doit pouvoir se suffire à elle-même. Par exemple, l'expression suivante devrait retourner un tableau à une colonne avec trois lignes : VALUES 'john', 'mary', 'paul';

À partir de la version 3.7.11 SQLite fait soutien Insertion à plusieurs rangs . Richard Hipp commente :

"Le nouvel insert multivalent n'est qu'une suggestion syntaxique (sic) pour l'insert composé. composé. Il n'y a pas d'avantage de performance dans un sens ou dans l'autre."

0 votes

Il n'y a pas d'avantage de performance dans un sens ou dans l'autre. - Pouvez-vous me dire où vous avez vu cette remarque ? Je ne l'ai trouvée nulle part.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X