Domanda

Avrei bisogno di rinominare alcune colonne in alcune tabelle in un database SQLite. So che una domanda simile è stato precedentemente richiesto su StackOverflow, ma era per SQL in generale e il caso di SQLite non è stato menzionato.

Dalla documentazione di SQLite per ALTER TABLE , ho capito che non è possibile fare un simile cosa " facilmente " (ovvero una singola istruzione ALTER TABLE).

Mi chiedevo che qualcuno sapesse di un modo SQL generico di fare una cosa del genere con SQLite.

È stato utile?

Soluzione

Ciò è stato appena risolto con 2018-09-15 (3.25.0)

  

Migliora il comando ALTER TABLE:

     
      
  • Aggiungi il supporto per rinominare le colonne all'interno di una tabella usando RENAME COLUMN oldname TO newname tabella RENAME COLUMN TO.
  •   
  • Correggi la funzionalità di ridenominazione della tabella in modo che aggiorni anche i riferimenti alla tabella rinominata nei trigger e nelle visualizzazioni.
  •   

Puoi trovare la nuova sintassi documentata in RENAME COLUMN

  

La sintassi <=> modifica il nome colonna del nome tabella tabella in nome nuova colonna. Il nome della colonna viene modificato sia all'interno della definizione della tabella stessa, sia all'interno di tutti gli indici, i trigger e le viste che fanno riferimento alla colonna. Se la modifica del nome della colonna comporterebbe un'ambiguità semantica in un trigger o in una vista, allora <=> fallisce con un errore e non vengono applicate modifiche.

 inserisci qui la descrizione dell'immagine Fonte immagine: https://www.sqlite.org/images /syntax/alter-table-stmt.gif

Esempio:

CREATE TABLE tab AS VALUES(1);

SELECT * FROM tab;

ALTER TABLE tab RENAME TO tab_new;

SELECT * FROM tab_new;

db-fiddle.com demo


Supporto Android

Al momento della scrittura, L'API 27 di Android utilizza il pacchetto SQLite versione 3.19 .

In base alla versione corrente utilizzata da Android e che questo aggiornamento arriverà nella versione 3.25.0 di SQLite, direi che hai un po 'di attesa (circa API 33) prima che il supporto per questo venga aggiunto ad Android.

E anche in questo caso, se è necessario supportare versioni precedenti all'API 33, non sarà possibile utilizzarlo.

Altri suggerimenti

Supponi di avere una tabella e di dover rinominare " colb " a " col_b " ;:

Prima rinominare la vecchia tabella:

ALTER TABLE orig_table_name RENAME TO tmp_table_name;

Quindi creare la nuova tabella, in base alla tabella precedente ma con il nome della colonna aggiornato:

CREATE TABLE orig_table_name (
  col_a INT
, col_b INT
);

Quindi copia il contenuto dalla tabella originale.

INSERT INTO orig_table_name(col_a, col_b)
SELECT col_a, colb
FROM tmp_table_name;

Infine, elimina la vecchia tabella.

DROP TABLE tmp_table_name;

Anche avvolgere tutto questo in BEGIN TRANSACTION; e COMMIT; è probabilmente una buona idea.

Sebbene sia vero che non esiste ALTER COLUMN, se si desidera solo rinominare la colonna, eliminare il vincolo NOT NULL o modificare il tipo di dati, è possibile utilizzare il seguente set di comandi:

Nota: questi comandi hanno il potenziale per corrompere il database, quindi assicurati di avere un backup

PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;

Dovrai chiudere e riaprire la connessione o svuotare il database per ricaricare le modifiche nello schema.

Ad esempio:

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT NULL);  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
Error: BOOKS.publication_date may not be NULL  
sqlite> PRAGMA writable_schema = 1; 
sqlite> UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';  
sqlite> PRAGMA writable_schema = 0;  
sqlite> .q  

Y:\> sqlite3 booktest  
SQLite version 3.7.4  
Enter ".help" for instructions  
Enter SQL statements terminated with a ";"  
sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
sqlite> .q  

SEGUENTI RIFERIMENTI:


pragma writable_schema
Quando questo pragma è attivo, le tabelle SQLITE_MASTER in cui è possibile modificare il database utilizzando le normali istruzioni UPDATE, INSERT e DELETE. Attenzione: l'uso improprio di questo pragma può facilmente provocare un file di database corrotto.

alter table
SQLite supporta un sottoinsieme limitato di ALTER TABLE. Il comando ALTER TABLE in SQLite consente all'utente di rinominare una tabella o di aggiungere una nuova colonna a una tabella esistente. Non è possibile rinominare una colonna, rimuovere una colonna o aggiungere o rimuovere vincoli da una tabella.

ALTER TABLE SYNTAX

Scavando, ho trovato questo strumento grafico multipiattaforma (Linux | Mac | Windows) chiamato Browser DB per SQLite che in realtà consente di rinominare le colonne in modo molto intuitivo!

Modifica | Modifica tabella | Seleziona tabella | Modifica campo. Fare clic fare clic! Voila!

Tuttavia, se qualcuno vuole condividere un modo programmatico di farlo, sarei felice di saperlo!

Di recente ho dovuto farlo in SQLite3 con una tabella denominata punti con le colonne id, lon, lat . Erroneamente, quando la tabella è stata importata, i valori di latitudine sono stati memorizzati nella colonna lon e viceversa, quindi una soluzione ovvia sarebbe quella di rinominare quelle colonne. Quindi il trucco era:

create table points_tmp as select id, lon as lat, lat as lon from points;
drop table points;
alter table points_tmp rename to points;

Spero che ti sia utile!

Citando la documentazione sqlite :

  

SQLite supporta un sottoinsieme limitato di   ALTER TABLE. Il comando ALTER TABLE   in SQLite consente all'utente di rinominare a   tabella o per aggiungere una nuova colonna a un   tavolo esistente. Non è possibile rinominare una colonna, rimuovere una colonna o aggiungere o rimuovere vincoli da una tabella.

Quello che puoi fare ovviamente è, creare una nuova tabella con il nuovo layout, SELECT * FROM old_table e riempire la nuova tabella con i valori che riceverai.

Prima di tutto, questa è una di quelle cose che mi schiaffeggia di sorpresa: la ridenominazione di una colonna richiede la creazione di una tabella completamente nuova e la copia dei dati dalla vecchia tabella alla nuova tabella ...

La GUI su cui sono arrivato per eseguire operazioni SQLite è Base . Ha una bella finestra di registro che mostra tutti i comandi che sono stati eseguiti. Effettuare una ridenominazione di una colonna tramite Base popola la finestra di registro con i comandi necessari:

Finestra registro di base

Questi possono quindi essere facilmente copiati e incollati dove potresti averne bisogno. Per me, è un file di migrazione ActiveAndroid . Un bel tocco, inoltre, è che i dati copiati includono solo i comandi SQLite, non i timestamp, ecc.

Speriamo che questo risparmi tempo ad alcune persone.

cambia la colonna della tabella < id > a < _id >

 String LastId = "id";

    database.execSQL("ALTER TABLE " + PhraseContract.TABLE_NAME + " RENAME TO " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("CREATE TABLE " + PhraseContract.TABLE_NAME
    +"("
            + PhraseContract.COLUMN_ID + " INTEGER PRIMARY KEY,"
            + PhraseContract.COLUMN_PHRASE + " text ,"
            + PhraseContract.COLUMN_ORDER  + " text ,"
            + PhraseContract.COLUMN_FROM_A_LANG + " text"
    +")"
    );
    database.execSQL("INSERT INTO " +
            PhraseContract.TABLE_NAME + "("+ PhraseContract.COLUMN_ID +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +")" +
            " SELECT " + LastId +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +
            " FROM " + PhraseContract.TABLE_NAME + "old");
    database.execSQL("DROP TABLE " + PhraseContract.TABLE_NAME + "old");

Come accennato in precedenza, esiste uno strumento SQLite Database Browser, che lo fa. Fortunatamente, questo strumento tiene un registro di tutte le operazioni eseguite dall'utente o dall'applicazione. Facendolo una volta e guardando il registro dell'applicazione, vedrai il codice in questione. Copia la query e incolla come richiesto. Ha funzionato per me. Spero che questo aiuti

Crea una nuova colonna con il nome della colonna desiderata: COLNew.

ALTER TABLE {tableName} ADD COLUMN COLNew {type};

Copia il contenuto della vecchia colonna COLOld nella nuova colonna COLNew.

INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}

Nota: le parentesi sono necessarie nella riga sopra.

Dalla documentazione ufficiale

Una procedura più semplice e veloce può facoltativamente essere utilizzata per alcune modifiche che non influiscono in alcun modo sul contenuto del disco. La seguente procedura più semplice è appropriata per rimuovere i vincoli CHECK o FOREIGN KEY o NOT NULL, rinominare le colonne o aggiungere o rimuovere o modificare i valori predefiniti su una colonna.

  1. Avvia una transazione.

  2. Esegui PRAGMA schema_version per determinare il numero di versione dello schema corrente. Questo numero sarà necessario per il passaggio 6 di seguito.

  3. Attiva la modifica dello schema usando PRAGMA writable_schema = ON.

  4. Esegui un'istruzione UPDATE per modificare la definizione della tabella X nella tabella sqlite_master: UPDATE sqlite_master SET sql = ... WHERE type = 'table' AND name = 'X';

    Attenzione: apportare una modifica alla tabella sqlite_master in questo modo renderà il database corrotto e illeggibile se la modifica contiene un errore di sintassi. Si suggerisce di eseguire test accurati dell'istruzione UPDATE su un database vuoto separato prima di utilizzarlo su un database contenente dati importanti.

  5. Se la modifica alla tabella X interessa anche altre tabelle o indici o trigger sono viste all'interno dello schema, eseguire le istruzioni UPDATE per modificare anche gli altri indici e viste delle tabelle. Ad esempio, se il nome di una colonna cambia, è necessario modificare tutti i vincoli, i trigger, gli indici e le viste FOREIGN KEY che fanno riferimento a quella colonna.

    Attenzione: ancora una volta, apportare modifiche alla tabella sqlite_master in questo modo renderà il database corrotto e illeggibile se la modifica contiene un errore. Testare attentamente l'intera procedura su un database di test separato prima di utilizzarlo su un database contenente dati importanti e / o eseguire copie di backup di database importanti prima di eseguire questa procedura.

  6. Incrementa il numero di versione dello schema usando PRAGMA schema_version = X dove X è uno in più rispetto al vecchio numero di versione dello schema trovato nel passaggio 2 sopra.

  7. Disabilita la modifica dello schema usando PRAGMA writable_schema = OFF.

  8. (Opzionale) Eseguire PRAGMA integral_check per verificare che le modifiche allo schema non abbiano danneggiato il database.

  9. Conferma la transazione avviata al passaggio 1 sopra.

Un'opzione, se ne hai bisogno in un pizzico, e se la tua colonna iniziale è stata creata con un valore predefinito, è quella di creare la nuova colonna desiderata, copiarne il contenuto e sostanzialmente " ;andon " la vecchia colonna (rimane presente, ma non la usi / aggiorni, ecc.)

es:

alter table TABLE_NAME ADD COLUMN new_column_name TYPE NOT NULL DEFAULT '';
update TABLE_NAME set new_column_name = old_column_name;
update TABLE_NAME set old_column_name = ''; -- abandon old column, basically

Questo lascia dietro una colonna (e se è stato creato con NOT NULL ma senza un valore predefinito, gli inserimenti futuri che lo ignorano potrebbero fallire), ma se è solo una tabella usa e getta, i compromessi potrebbero essere accettabili. Altrimenti usa una delle altre risposte menzionate qui o un database diverso che consente di rinominare le colonne.

CASO 1: SQLite 3.25.0+

Solo la versione 3.25.0 di SQLite supporta la ridenominazione delle colonne. Se il tuo dispositivo soddisfa questo requisito, le cose sono abbastanza semplici. La query seguente risolverebbe il tuo problema:

ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";

CASO 2: versioni precedenti di SQLite

Devi seguire un approccio diverso per ottenere il risultato che potrebbe essere un po 'complicato

Ad esempio, se hai una tabella come questa:

CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)

E se desideri cambiare il nome della colonna Location

Passaggio 1: rinominare la tabella originale:

ALTER TABLE student RENAME TO student_temp;

Passaggio 2: ora crea una nuova tabella student con il nome di colonna corretto:

CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)

Passaggio 3: copia i dati dalla tabella originale alla nuova tabella:

INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;

Nota: il comando sopra dovrebbe essere tutto su una riga.

Passaggio 4: rilascia la tabella originale:

DROP TABLE student_temp;

Con questi quattro passaggi è possibile modificare manualmente qualsiasi tabella SQLite. Tieni presente che dovrai anche ricreare tutti gli indici, i visualizzatori o i trigger sulla nuova tabella.

Dalla versione 2018-09-15 (3.25.0) sqlite supporta la ridenominazione delle colonne

https://sqlite.org/changes.html

sqlite3 yourdb .dump > /tmp/db.txt
modifica /tmp/db.txt cambia il nome della colonna in Crea riga
sqlite2 yourdb2 < /tmp/db.txt
mv / move yourdb2 yourdb

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top