una tipos studio para hacer datos crear como comandos almacenamiento sql sqlite syntax

tipos - ¿Es posible insertar varias filas a la vez en una base de datos SQLite?



crear base de datos sqlite windows (24)

A partir de la versión 3.7.11, SQLite admite la inserción de varias filas. Richard Hipp comenta:

Estoy usando 3.6.13

Yo mando así:

insert into xtable(f1,f2,f3) select v1 as f1, v2 as f2, v3 as f3 union select nextV1+, nextV2+, nextV3+

Con 50 registros insertados a la vez, solo toma un segundo o menos.

Es cierto que usar sqlite para insertar varias filas a la vez es muy posible. Por @Andy escribió.

gracias Andy +1

En MySQL puedes insertar múltiples filas como esta:

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

Sin embargo, recibo un error cuando intento hacer algo como esto. ¿Es posible insertar varias filas a la vez en una base de datos SQLite? ¿Cuál es la sintaxis para hacer eso?


actualizar

Como señala BrianCampbell aquí , SQLite 3.7.11 y superior ahora admiten la sintaxis más simple de la publicación original . Sin embargo, el enfoque mostrado aún es apropiado si desea la máxima compatibilidad en las bases de datos heredadas.

respuesta original

Si tuviera privilegios, pondría la respuesta de Andy : puedes insertar varias filas en SQLite, solo necesitas una sintaxis diferente . Para que quede perfectamente claro, el ejemplo de OPs MySQL:

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

Esto puede ser refundido en SQLite como:

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''

una nota sobre el rendimiento

Originalmente utilicé esta técnica para cargar de manera eficiente grandes conjuntos de datos de Ruby on Rails. Sin embargo , como apunta Jaime Cook , no está claro que esto sea más rápido para envolver INSERTs individuales dentro de una sola transacción:

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

Si la eficiencia es su objetivo, debe intentar esto primero.

una nota sobre UNION vs UNION ALL

Como varias personas comentaron, si usa UNION ALL (como se muestra arriba), todas las filas se insertarán, por lo que en este caso, obtendría cuatro filas de data1, data2 . Si omite el ALL , se eliminarán las filas duplicadas (y la operación probablemente será un poco más lenta). Estamos usando UNION ALL ya que coincide más con la semántica de la publicación original.

Para concluir

PD: Por favor, +1 respuesta de Andy , no mía! Presentó la solución primero.


A partir de la versión 2012-03-20 (3.7.11), sqlite admite la siguiente sintaxis INSERT:

INSERT INTO ''tablename'' (''column1'', ''column2'') VALUES (''data1'', ''data2''), (''data3'', ''data4''), (''data5'', ''data6''), (''data7'', ''data8'');

Lea la documentación: http://www.sqlite.org/lang_insert.html

PD: Por favor, +1 a la respuesta / respuesta de Brian Campbell. ¡no es mio! Presentó la solución primero.


Alex tiene razón: la declaración "seleccionar ... unión" perderá el orden, lo cual es muy importante para algunos usuarios. Incluso cuando inserta en un orden específico, sqlite cambia las cosas, así que prefiera usar transacciones si el pedido de inserciones es importante.

create table t_example (qid int not null, primary key (qid)); begin transaction; insert into "t_example" (qid) values (8); insert into "t_example" (qid) values (4); insert into "t_example" (qid) values (9); end transaction; select rowid,* from t_example; 1|8 2|4 3|9


Como han dicho los otros carteles, SQLite no admite esta sintaxis. No sé si los INSERT compuestos son parte del estándar SQL, pero en mi experiencia no están implementados en muchos productos.

Además, debe tener en cuenta que el rendimiento de INSERT en SQLite se mejora considerablemente si ajusta varios INSERT en una transacción explícita.


El problema con el uso de la transacción es que también bloquea la tabla para la lectura. Entonces, si realmente tiene muchos datos para insertar y necesita acceder a sus datos, por ejemplo, una vista previa o algo así, esto no funciona bien.

El problema con la otra solución es que se pierde el orden de la inserción

insert into mytable (col) select ''c'' union select ''d'' union select ''a'' union select ''b'';

En el sqlite los datos serán almacenados a, b, c, d ...


En sqlite 3.7.2:

INSERT INTO table_name (column1, column2) SELECT ''value1'', ''value1'' UNION SELECT ''value2'', ''value2'' UNION SELECT ''value3'', ''value3''

y así


Escribí un código Ruby para generar una única inserción de múltiples filas de 500 elementos a partir de una serie de sentencias de inserción que fue considerablemente más rápida que ejecutar las inserciones individuales. Luego intenté simplemente envolver las inserciones múltiples en una sola transacción y descubrí que podía obtener el mismo tipo de aceleración con mucho menos código.

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


Me sorprende que nadie haya mencionado declaraciones preparadas . A menos que esté utilizando SQL por su cuenta y no en ningún otro idioma, entonces creo que las declaraciones preparadas envueltas en una transacción serían la forma más eficiente de insertar múltiples filas.


No puedes, pero no creo que te pierdas nada.

Debido a que llama a sqlite siempre en proceso, casi no importa en el rendimiento si ejecuta 1 instrucción de inserción o 100 instrucciones de inserción. Sin embargo, la confirmación lleva mucho tiempo, así que coloque esas 100 inserciones dentro de una transacción.

Sqlite es mucho más rápido cuando utilizas consultas parametrizadas (se necesita mucho menos análisis), por lo que no concatenaré grandes afirmaciones como esta:

insert into mytable (col1, col2) select ''a'',''b'' union select ''c'',''d'' union ...

Deben analizarse una y otra vez porque cada declaración concatenada es diferente.



Sí, SQL puede hacer esto, pero con una sintaxis diferente. La documentación de sqlite es bastante buena, por cierto. También le dirá que la única forma de insertar varias filas es usar una declaración de selección como fuente de los datos que se insertarán.


Sí, a partir de SQLite 3.7.11 esto es compatible con SQLite. De la documentación de SQLite :

(cuando esta respuesta fue escrita originalmente, esto no fue compatible)

Para la compatibilidad con versiones anteriores de SQLite, puede usar el truco sugerido por andy and fearless_fool usando UNION , pero para 3.7.11 y posteriores se debe preferir la sintaxis más simple descrita aquí.


Sí, es posible, pero no con los valores de inserción usuales separados por comas.

Prueba esto...

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

Sí, es un poco feo pero lo suficientemente fácil como para automatizar la generación de la declaración a partir de un conjunto de valores. Además, parece que solo necesita declarar los nombres de las columnas en la primera selección.


Según esta página no es compatible:

  • 2007-12-03: No se admite el uso de INSERT de varias filas alias INSERT compuesto.

INSERT INTO table (col1, col2) VALUES (''row1col1'', ''row1col2''), (''row2col1'', ''row2col2''), ...

En realidad, de acuerdo con el estándar SQL92, una expresión VALUES debería poder sostenerse sobre sí misma. Por ejemplo, lo siguiente debería devolver una tabla de una columna con tres filas: VALUES ''john'', ''mary'', ''paul'';

A partir de la versión 3.7.11, SQLite admite la inserción de varias filas . Richard Hipp comenta:

"El nuevo inserto multivalor es simplemente una sugerencia sintáctica (sic) para el inserto compuesto. No hay ventaja de rendimiento de una manera u otra".


Si estás usando bash shell puedes usar esto:

time bash -c $'' FILE=/dev/shm/test.db sqlite3 $FILE "create table if not exists tab(id int);" sqlite3 $FILE "insert into tab values (1),(2)" for i in 1 2 3 4; do sqlite3 $FILE "INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5"; done; sqlite3 $FILE "select count(*) from tab;"''

O si está en CLI de sqlite, entonces necesita hacer esto:

create table if not exists tab(id int);" insert into tab values (1),(2); INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5; INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5; INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5; INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5; select count(*) from tab;

¿Como funciona? Hace uso de eso si tabla tab :

id int ------ 1 2

luego select a.id, b.id from tab a, tab b devuelve

a.id int | b.id int ------------------ 1 | 1 2 | 1 1 | 2 2 | 2

y así. Después de la primera ejecución insertamos 2 filas, luego 2 ^ 3 = 8. (tres porque tenemos la tab a, tab b, tab c )

Después de la segunda ejecución insertamos adicional (2+8)^3=1000 filas

A continuación, insertamos aproximadamente max(1000^3, 5e5)=500000 filas y así sucesivamente ...

Este es el método más rápido conocido para mí de poblar bases de datos SQLite.


Soy capaz de hacer la consulta dinámica. Esta es mi mesa:

CREATE TABLE "tblPlanner" ("probid" text,"userid" TEXT,"selectedtime" DATETIME,"plannerid" TEXT,"isLocal" BOOL,"applicationid" TEXT, "comment" TEXT, "subject" TEXT)

y estoy obteniendo todos los datos a través de un JSON , así que después de obtener todo dentro de un NSArray , seguí esto:

NSMutableString *query = [[NSMutableString alloc]init]; for (int i = 0; i < arr.count; i++) { NSString *sqlQuery = nil; sqlQuery = [NSString stringWithFormat:@" (''%@'', ''%@'', ''%@'', ''%@'', ''%@'', ''%@'', ''%@'', ''%@''),", [[arr objectAtIndex:i] objectForKey:@"plannerid"], [[arr objectAtIndex:i] objectForKey:@"probid"], [[arr objectAtIndex:i] objectForKey:@"userid"], [[arr objectAtIndex:i] objectForKey:@"selectedtime"], [[arr objectAtIndex:i] objectForKey:@"isLocal"], [[arr objectAtIndex:i] objectForKey:@"subject"], [[arr objectAtIndex:i] objectForKey:@"comment"], [[NSUserDefaults standardUserDefaults] objectForKey:@"applicationid"] ]; [query appendString:sqlQuery]; } // REMOVING LAST COMMA NOW [query deleteCharactersInRange:NSMakeRange([query length]-1, 1)]; query = [NSString stringWithFormat:@"insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values%@",query];

Y finalmente la consulta de salida es esta:

insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values <append 1> (''pl1176428260'', '''', ''US32552'', ''2013-06-08 12:00:44 +0000'', ''0'', ''subj'', ''Hiss'', ''ap19788''), <append 2> (''pl2050411638'', '''', ''US32552'', ''2013-05-20 10:45:55 +0000'', ''0'', ''TERI'', ''Yahoooooooooo'', ''ap19788''), <append 3> (''pl1828600651'', '''', ''US32552'', ''2013-05-21 11:33:33 +0000'', ''0'', ''test'', ''Yest'', ''ap19788''), <append 4> (''pl549085534'', '''', ''US32552'', ''2013-05-19 11:45:04 +0000'', ''0'', ''subj'', ''Comment'', ''ap19788''), <append 5> (''pl665538927'', '''', ''US32552'', ''2013-05-29 11:45:41 +0000'', ''0'', ''subj'', ''1234567890'', ''ap19788''), <append 6> (''pl1969438050'', '''', ''US32552'', ''2013-06-01 12:00:18 +0000'', ''0'', ''subj'', ''Cmt'', ''ap19788''), <append 7> (''pl672204050'', '''', ''US55240280'', ''2013-05-23 12:15:58 +0000'', ''0'', ''aassdd'', ''Cmt'', ''ap19788''), <append 8> (''pl1019026150'', '''', ''US32552'', ''2013-06-08 12:15:54 +0000'', ''0'', ''exists'', ''Cmt'', ''ap19788''), <append 9> (''pl790670523'', '''', ''US55240280'', ''2013-05-26 12:30:21 +0000'', ''0'', ''qwerty'', ''Cmt'', ''ap19788'')

que también funciona bien con el código y puedo guardar todo en SQLite con éxito.

Antes de esto hice dinámicas las consultas de UNION pero eso comenzó a dar un error de sintaxis. De todos modos, esto está funcionando bien para mí.


Sqlite3 no puede hacer eso directamente en SQL, excepto a través de SELECT, y si bien SELECT puede devolver una "fila" de expresiones, no conozco ninguna forma de hacer que devuelva una columna falsa.

Sin embargo, el CLI puede hacerlo:

.import FILE TABLE Import data from FILE into TABLE .separator STRING Change separator used by output mode and .import $ sqlite3 /tmp/test.db SQLite version 3.5.9 Enter ".help" for instructions sqlite> create table abc (a); sqlite> .import /dev/tty abc 1 2 3 99 ^D sqlite> select * from abc; 1 2 3 99 sqlite>

Si coloca un bucle alrededor de un INSERT, en lugar de usar el comando .import la CLI, asegúrese de seguir los consejos de las Preguntas frecuentes de sqlite para la velocidad de INSERT:

Por defecto, cada instrucción INSERT es su propia transacción. Pero si rodea varias instrucciones INSERT con BEGIN ... COMMIT, entonces todas las inserciones se agrupan en una sola transacción. El tiempo necesario para cometer la transacción se amortiza en todas las declaraciones de inserción adjuntas y, por lo tanto, el tiempo por instrucción de inserción se reduce considerablemente.

Otra opción es ejecutar PRAGMA synchronous = OFF. Este comando hará que SQLite no espere a que los datos alcancen la superficie del disco, lo que hará que las operaciones de escritura parezcan mucho más rápidas. Pero si pierde el poder en medio de una transacción, su archivo de base de datos podría dañarse.


Tengo una consulta como la de abajo, pero con el controlador ODBC, SQLite tiene un error con "," dice. Ejecuto vbscript en HTA (Html ​​Application).

INSERT INTO evrak_ilac_iliskileri (evrak_id, ilac_id, baglayan_kullanici_id, tarih) VALUES (4150,762,1,datetime()),(4150,9770,1,datetime()),(4150,6609,1,datetime()),(4150,3628,1,datetime()),(4150,9422,1,datetime())


en mysql lite no puede insertar varios valores, pero puede ahorrar tiempo al abrir la conexión solo una vez, luego hacer todas las inserciones y luego cerrar la conexión. Ahorra mucho tiempo


fearless_fool tiene una gran respuesta para versiones anteriores. Solo quería agregar que necesita asegurarse de que tiene todas las columnas enumeradas. Entonces, si tiene 3 columnas, debe asegurarse de que seleccionar actúe en 3 columnas.

Ejemplo: Tengo 3 columnas, pero solo quiero insertar 2 columnas de datos. Supongamos que no me importa la primera columna porque es un ID de entero estándar. Yo podría hacer lo siguiente ...

INSERT INTO ''tablename'' SELECT NULL AS ''column1'', ''data1'' AS ''column2'', ''data2'' AS ''column3'' UNION SELECT NULL, ''data3'', ''data4'' UNION SELECT NULL, ''data5'', ''data6'' UNION SELECT NULL, ''data7'', ''data8''

Nota: Recuerde que la declaración "seleccionar ... unión" perderá el pedido. (Desde AG1)



INSERT INTO TABLE_NAME (DATA1, DATA2) VALUES (VAL1, VAL2), (VAL1, VAL2), (VAL1, VAL2), (VAL1, VAL2), (VAL1, VAL2), (VAL1, VAL2), (VAL1, VAL2), (VAL1, VAL2);


INSERT INTO tabela(coluna1,coluna2) SELECT ''texto'',''outro'' UNION ALL SELECT ''mais texto'',''novo texto'';