2009-05-30 11 views
7

Come inserire bulk con SQLite?Come inserire bulk con SQLite?

L'ho cercato e mi sembra di inserire un inserto con un'istruzione select. Ho cercato su Google, ho esaminato gli esempi e sembrano tutti copiati da una tabella a un'altra o non sono compatibili con SQLite. Voglio fare qualcosa di simile

"INSERT INTO user_msg_media (recipientId, mediaId, catagory, current_media_date) " + 
"VALUES(@mediaId, @catagory, @current_media_date)"; 
where the value of recipientId is the watcher from each of 
"SELECT watcher FROM userwatch WHERE [email protected]"; 

Ho provato il codice qui sotto e ottengo l'errore "errore di SQLite tale colonna: watcher"

 command.CommandText = 
      "CREATE TABLE if not exists user_msg_media(" + 
      "msgId  INTEGER PRIMARY KEY, " + 
      "recipientId INTEGER, " + 
      "mediaId  INTEGER, " + 
      "catagory  INTEGER, " + 
      "current_date DATE);"; 
     command.ExecuteNonQuery(); 

     //user media 
     command.CommandText = 
      "CREATE TABLE if not exists user_watch(" + 
      "indx INTEGER PRIMARY KEY, " + 
      "watcher INTEGER, " + 
      "watched INTEGER);"; 
     command.ExecuteNonQuery(); 
     //... 

    command.CommandText = "SELECT watcher FROM user_watch WHERE watched=:watched;"; 
    command.Parameters.Add(":watched", DbType.Int64).Value = 1; 
    command.ExecuteNonQuery(); //is ok 

    command.CommandText = 
     "INSERT INTO user_msg_media (recipientId, mediaId, catagory, current_media_date) " + 
     "SELECT watcher, :mediaId, :category, :current_media_date" + 
     "FROM user_watch WHERE watched=:watched;"; 
    command.Parameters.Add(":mediaId", DbType.Int64).Value = 0; 
    command.Parameters.Add(":category", DbType.Int64).Value = 0; 
    command.Parameters.Add(":current_media_date", DbType.Int64).Value = 0; 
    command.Parameters.Add(":watched", DbType.Int64).Value = 1; 
    command.ExecuteNonQuery(); 
+0

Si sta utilizzando System.Data.Sqlite? –

+0

Nota la tabella CREATE per usr_msg_media rende una colonna denominata current_date, ma l'INSERT prova a impostare current_media_date invece: Credo che questo errore sia stato diagnosticato erroneamente da SQLite (si confonde e afferma che la colonna mancante è watcher), poiché posso riprodurre messaggio di errore errato - ma se risolvo l'errore effettivo, funziona, vedi il codice di esempio Python nella mia risposta. –

risposta

2

SQLite non supporta la notazione @variable, ma (utilizzando lo stile di nome-segnaposto come sostenuto dalla Python legame di SQLite per chiarezza) questo dovrebbe funzionare:

INSERT INTO user_msg_media (userId, mediaId, catagory, current_media_date) 
SELECT watcher, :mediaId, :category, :current_media_date 
FROM userwatch WHERE watched=:watched 

Edit: SQLite sembra essere misdiagnosing quale colonna nome è sbagliato. Con i nomi di colonna tutti i fissi, il seguente codice Python funziona per me (non so cosa altra lingua si sta utilizzando, Python di quello più comodo per me di interagire con SQLite):

import sqlite3 as sq 

con = sq.connect(':memory:') 
cur = con.cursor() 
cur.execute("CREATE TABLE if not exists user_msg_media(" + 
      "msgId  INTEGER PRIMARY KEY, " + 
      "recipientId INTEGER, " + 
      "mediaId  INTEGER, " + 
      "catagory  INTEGER, " + 
      "current_date DATE)") 
cur.execute("CREATE TABLE if not exists user_watch(" + 
      "indx INTEGER PRIMARY KEY, " + 
      "watcher INTEGER, " + 
      "watched INTEGER)") 

cur.execute("INSERT INTO user_watch VALUES (1, 2, 3)") 

cur.execute("SELECT watcher FROM user_watch WHERE watched=:watched", 
      dict(watched=3)) 
print cur.fetchall() 

print cur.execute("INSERT INTO user_msg_media (recipientId, mediaId, catagory, current_date) " + 
     "SELECT watcher, :mediaId, :category, :current_media_date " + 
     "FROM user_watch WHERE watched=:watched;", 
     dict(mediaId=0, category=0, current_media_date=0, watched=3) 
) 

cur.execute("SELECT * FROM user_msg_media") 
print cur.fetchall() 

Ma se ho riprodotto disallineamenti di SQL come current_date vs current_media_date, posso far diagnosticare erroneamente che la colonna mancante sia watcher, anche se quella colonna è di fatto valida. Vuoi provare a inserire questo codice corretto nella tua lingua preferita e vedere come si comporta?

+0

L'ho provato, ho ricevuto un errore di colonna di questo tipo. –

+0

Questo suggerisce che uno dei nomi delle colonne è scritto erroneamente - qual è l'istruzione 'CREATE TABLE' per la tabella' user_msg_media', quindi? –

+0

(vale a dire, supponendo che la lingua che stai usando usi la stessa sintassi per segnaposto come pysqlite e passi anche la dict, l'hash o qualsiasi altra cosa) ... –

1

Io suggerirei di usare Dapper ORM da parte dei nostri amici a StackOverflow. Se guardi la sezione sul rendimento, non puoi ottenere molto più velocemente di Dapper.

eseguire un comando più volte
la stessa firma permette inoltre di comodo ed efficiente eseguire un comando più volte (ad esempio per i dati bulk-carico)

Esempio utilizzo:

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)", 
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } } 
); // 3 rows inserted: "1,1", "2,2" and "3,3" 

Funziona per qualsiasi parametro che implementa IEnumerable per alcuni T.

+0

haha, 2,5 anni di ritardo. usando dapper (o seleziona) e il mio orm (per tutto il resto) che prende a calci il sedere da subsonico e l'altro ha chiamato gli orms –

+1

Sono lieto di sapere che stai avendo successo con Dapper. applicazione. – BrokeMyLegBiking

Problemi correlati