2009-11-11 18 views
7

Questo sembra abbastanza semplice: voglio duplicare un riga in una tabella SQLite:Come inserire righe duplicate in SQLite con un ID univoco?

INSERT INTO table SELECT * FROM table WHERE rowId=5; 

Se non ci fossero le dichiarazioni di colonna univoci esplicite, la dichiarazione avrebbe funzionato, ma prima colonna della tabella è dichiarato rowID INTEGER NOT NULL PRIMARY KEY. C'è un modo per creare una semplice istruzione come quella sopra che funziona senza conoscere lo schema della tabella (a parte la prima colonna)?

risposta

5

Bene, poiché non ero in grado di farlo nel modo che volevo, ho fatto ricorso all'ID della riga implicita, che ha lo stesso nome della colonna rowId definita in modo esplicito, quindi ora posso usare la query I aveva nella domanda, e inserirà tutti i dati con una nuova rigaId. Per mantenere il resto del programma in funzione, ho appena cambiato SELECT * FROM table in SELECT rowId,* FROM table e tutto va bene.

+1

Questo non è lavoro per me dice 'fornito n + 1 valori dove n colonne disponibili' –

8

No. È necessario conoscere lo schema della tabella per scrivere correttamente l'istruzione di inserimento.

Devi essere in grado di scrivere la dichiarazione in forma di:

insert into Table (column1, column2, column3) 
select column1, column2, column3 
from OtherTable 
where rowId = 5 
0

assolutamente alcun modo per fare questo. La dichiarazione della chiave primaria implica che questo campo è unico. Non puoi avere un PK non unico. Non c'è modo di creare una riga con PK esistente nella stessa tabella.

+2

La mia domanda era più simile a, come posso specificare NULL per il rowId in modo che prenda automaticamente il prossimo ID disponibile –

19

Questa operazione può essere eseguita utilizzando la sintassi * senza conoscere lo schema della tabella (diverso dal nome della chiave primaria). Il trucco è creare una tabella temporanea usando la sintassi "CREATE TABLE AS".

In questo esempio presumo che esista una tabella popolata esistente denominata "src" con una CHIAVE PRIMARIA INTEGER chiamata "id", nonché diverse altre colonne. Per duplicare le righe di "src", utilizzare il seguente SQL in SQLite3:

CREATE TEMPORARY TABLE tmp AS SELECT * FROM src; 
UPDATE tmp SET id = NULL; 
INSERT INTO src SELECT * FROM tmp; 
DROP TABLE tmp; 

L'esempio sopra duplica tutte le righe della tabella "src". Per duplicare solo una riga desiderata, è sufficiente aggiungere una clausola WHERE alla prima riga. Questo esempio funziona perché la tabella "tmp" non ha alcun vincolo di chiave primaria, ma "src" lo fa. L'inserimento di chiavi primarie NULL in src fa sì che vengano dati valori auto generati.

Dalla documentazione SQLite: http://www.sqlite.org/lang_createtable.html

A "CREATE TABLE ... AS SELECT" istruzione crea e popola una tabella del database sulla base dei risultati di un'istruzione SELECT. Una tabella creata utilizzando CREATE TABLE AS non ha PRIMARY KEY e nessun vincolo di alcun tipo.

Se si vuole essere davvero fantasiosi, è possibile aggiungere un trigger che aggiorna una terza tabella che associa le vecchie chiavi primarie alle chiavi primarie appena generate.

+1

I non mi piacciono molto i workaround per manovre banali. Ma questo è il modo migliore per farlo. –