tutorial - sqlite win 10




È possibile inserire più righe alla volta in un database SQLite? (16)

A partire dalla versione 3.7.11 SQLite supporta l'inserimento multi-riga. Richard Hipp commenta:

Sto usando 3.6.13

Io comando così:

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

Con 50 record inseriti alla volta, ci vuole solo un secondo o meno.

È vero che usare sqlite per inserire più righe alla volta è molto possibile. Per @Andy ha scritto.

grazie Andy +1

In MySQL puoi inserire più righe come questa:

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

Tuttavia, sto ricevendo un errore quando provo a fare qualcosa di simile. È possibile inserire più righe alla volta in un database SQLite? Qual è la sintassi per farlo?


aggiornare

Come sottolinea BrianCampbell qui , SQLite 3.7.11 e versioni successive ora supporta la sintassi più semplice del post originale . Tuttavia, l'approccio mostrato è ancora appropriato se si desidera la massima compatibilità tra i database legacy.

risposta originale

Se avessi i privilegi, avrei dovuto rispondere ad andy : puoi inserire più righe in SQLite, hai solo bisogno di una sintassi diversa . Per rendere perfettamente chiaro, l'esempio MySQL OP:

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

Questo può essere riformulato in SQLite come:

     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 sulla performance

Inizialmente ho utilizzato questa tecnica per caricare in modo efficiente dataset di grandi dimensioni da Ruby on Rails. Tuttavia , come osserva Jaime Cook , non è chiaro che si tratti di singoli INSERTs più rapidi all'interno di una singola transazione:

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

Se l'efficienza è il tuo obiettivo, dovresti provare prima questo.

una nota su UNION vs UNION ALL

Come diverse persone hanno commentato, se si utilizza UNION ALL (come mostrato sopra), verranno inserite tutte le righe, quindi in questo caso si otterrebbero quattro righe di data1, data2 . Se si omette il valore ALL , allora le righe duplicate verranno eliminate (e l'operazione sarà presumibilmente un po 'più lenta). Stiamo usando UNION ALL poiché è più simile alla semantica del post originale.

in chiusura

PS: per favore +1 risposta di andy , non mia! Ha presentato la soluzione per prima.


Come hanno detto gli altri utenti, SQLite non supporta questa sintassi. Non so se gli INSERT composti fanno parte dello standard SQL, ma nella mia esperienza non sono implementati in molti prodotti.

Per inciso, è necessario tenere presente che le prestazioni INSERT in SQLite sono notevolmente migliorate se si inseriscono più INSERT in una transazione esplicita.


Dalla versione 2012-03-20 (3.7.11), sqlite supporta la seguente sintassi INSERT:

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

Leggi la documentazione: http://www.sqlite.org/lang_insert.html

PS: per favore, fai +1 alla risposta / risposta di Brian Campbell. non mio! Ha presentato la soluzione per prima.


Ho una query come sotto, ma con SQLite driver ODBC ha un errore con "," dice. Corro vbscript in HTA (applicazione Html).

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())

Il problema con l'utilizzo della transazione è il blocco della tabella anche per la lettura. Quindi se hai davvero molti dati da inserire e hai bisogno di accedere ai tuoi dati, per esempio un'anteprima o meno, in questo modo non funziona bene.

Il problema con l'altra soluzione è che si perde l'ordine di inserimento

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

Nel sqlite i dati saranno memorizzati a, b, c, d ...


Sì, è possibile, ma non con i soliti valori di inserimento separati da virgola.

Prova questo...

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

Sì, è un po 'brutto ma abbastanza facile da automatizzare la generazione della dichiarazione da un insieme di valori. Inoltre, sembra che devi solo dichiarare i nomi delle colonne nella prima selezione.



Se stai usando bash shell puoi usare questo:

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 se sei in CLI sqlite, allora devi fare questo:

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;

Come funziona? Lo usa se la tab tabella:

id int
------
1
2

quindi select a.id, b.id from tab a, tab b restituisce

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

e così via. Dopo la prima esecuzione inseriamo 2 righe, quindi 2 ^ 3 = 8. (tre perché abbiamo tab a, tab b, tab c )

Dopo la seconda esecuzione inseriamo ulteriori (2+8)^3=1000 righe

All'inizio, inseriamo il max(1000^3, 5e5)=500000 righe e così via ...

Questo è il metodo più rapido per me di popolamento del database SQLite.


Secondo questa pagina non è supportato:

  • 2007-12-03: INSERT multipiattaforma, ovvero INSERT composto non supportato.
  INSERT INTO table (col1, col2) VALUES 
      ('row1col1', 'row1col2'), ('row2col1', 'row2col2'), ...

In realtà, secondo lo standard SQL92, un'espressione VALUES dovrebbe essere in grado di stare su se stessa. Ad esempio, il seguente dovrebbe restituire una tabella a una colonna con tre righe: VALUES 'john', 'mary', 'paul';

A partire dalla versione 3.7.11 SQLite supporta l' inserimento multi-riga . Richard Hipp commenta:

"Il nuovo inserto multivalore è semplicemente sintattico suger (sic) per l'inserto composto: non ci sono vantaggi prestazionali in un modo o nell'altro".


Sono sorpreso che nessuno abbia menzionato dichiarazioni preparate . A meno che non si stia utilizzando SQL da solo e non in qualsiasi altra lingua, allora penserei che le istruzioni preparate racchiuse in una transazione sarebbero il modo più efficace di inserire più righe.


Sqlite3 non può farlo direttamente in SQL se non tramite una SELECT, e mentre SELECT può restituire una "riga" di espressioni, non conosco alcun modo per farlo restituire una colonna fasulla.

Tuttavia, la CLI può farlo:

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

Se fai un loop su un INSERT, invece di usare il comando CLI .import , assicurati di seguire il consiglio nelle FAQ sqlite per la velocità INSERT:

Per impostazione predefinita, ciascuna istruzione INSERT è la propria transazione. Ma se si circondano più istruzioni INSERT con BEGIN ... COMMIT, tutti gli inserimenti vengono raggruppati in un'unica transazione. Il tempo necessario per eseguire il commit della transazione viene ammortizzato su tutte le istruzioni di inserimento allegate e quindi il tempo per la dichiarazione di inserimento viene notevolmente ridotto.

Un'altra opzione è eseguire PRAGMA synchronous = OFF. Questo comando farà sì che SQLite non attenda che i dati raggiungano la superficie del disco, il che renderà le operazioni di scrittura molto più veloci. Ma se perdi energia nel bel mezzo di una transazione, il tuo file di database potrebbe essere corrotto.


fearless_fool ha un'ottima risposta per le versioni precedenti. Volevo solo aggiungere che è necessario assicurarsi di avere tutte le colonne elencate. Quindi, se hai 3 colonne, devi assicurarti che la selezione funzioni su 3 colonne.

Esempio: ho 3 colonne ma voglio solo inserire 2 colonne di dati. Supponiamo che non mi interessi della prima colonna perché è un ID intero standard. Potrei fare quanto segue ...

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: ricorda che l'istruzione "seleziona ... unione" perderà l'ordine. (Da AG1)


in mysql lite non puoi inserire più valori, ma puoi risparmiare tempo aprendo la connessione solo una volta e poi facendo tutti gli inserimenti e quindi chiudendo la connessione. Risparmia molto tempo


Se si utilizza il plugin firefox di Sqlite manager , supporta gli inserimenti di massa da INSERT SQL INSERT .

Infatti non supporta questo, ma Sqlite Browser (funziona su Windows, OS X, Linux)


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




syntax