type - sqlite rename table




ALTER TABLE ADD COLUMN SE NON ESISTE in SQLite (4)

Di recente abbiamo avuto la necessità di aggiungere colonne ad alcune delle nostre tabelle di database SQLite esistenti. Questo può essere fatto con ALTER TABLE ADD COLUMN . Certo, se il tavolo è già stato modificato, vogliamo lasciarlo da solo. Sfortunatamente, SQLite non supporta una clausola IF NOT EXISTS su ALTER TABLE .

La nostra soluzione attuale consiste nell'eseguire l'istruzione ALTER TABLE e ignorare eventuali errori di "nome della colonna duplicata", proprio come questo esempio di Python (ma in C ++).

Tuttavia, il nostro approccio abituale nell'impostare schemi di database è di avere uno script .sql contenente le istruzioni CREATE TABLE IF NOT EXISTS e CREATE INDEX IF NOT EXISTS , che possono essere eseguite utilizzando sqlite3_exec o lo sqlite3 riga di comando sqlite3 . Non possiamo mettere ALTER TABLE in questi file di script perché se quell'istruzione fallisce, qualsiasi cosa dopo non verrà eseguita.

Voglio avere le definizioni della tabella in un posto e non dividere tra i file .sql e .cpp. C'è un modo per scrivere una soluzione alternativa su ALTER TABLE ADD COLUMN IF NOT EXISTS in SQLite SQLite puro?


Ho un metodo SQL puro al 99%. L'idea è di eseguire la versione del tuo schema. Puoi farlo in due modi:

  • Utilizzare il comando pragma 'user_version' ( PRAGMA user_version ) per memorizzare un numero incrementale per la versione dello schema del database.

  • Memorizza il tuo numero di versione nella tua tabella definita.

In questo modo, all'avvio del software, è possibile controllare lo schema del database e, se necessario, eseguire la query ALTER TABLE , quindi incrementare la versione memorizzata. Questo è di gran lunga meglio che tentare vari aggiornamenti "ciechi", soprattutto se il tuo database cresce e cambia alcune volte nel corso degli anni.


SQLite supporta anche un'istruzione pragma chiamata "table_info" che restituisce una riga per colonna in una tabella con il nome della colonna (e altre informazioni sulla colonna). È possibile utilizzare questo in una query per verificare la colonna mancante e, se non presente, modificare la tabella.

PRAGMA table_info(foo_table_name)

http://www.sqlite.org/pragma.html#pragma_table_info



Una soluzione alternativa consiste nel creare semplicemente le colonne e rilevare l'eccezione / errore che si verifica se la colonna esiste già. Quando si aggiungono più colonne, aggiungerle in istruzioni ALTER TABLE separate in modo che un duplicato non impedisca la creazione degli altri.

Con sqlite-net , abbiamo fatto qualcosa di simile. Non è perfetto, dal momento che non possiamo distinguere errori sqlite duplicati da altri errori sqlite.

Dictionary<string, string> columnNameToAddColumnSql = new Dictionary<string, string>
{
    {
        "Column1",
        "ALTER TABLE MyTable ADD COLUMN Column1 INTEGER"
    },
    {
        "Column2",
        "ALTER TABLE MyTable ADD COLUMN Column2 TEXT"
    }
};

foreach (var pair in columnNameToAddColumnSql)
{
    string columnName = pair.Key;
    string sql = pair.Value;

    try
    {
        this.DB.ExecuteNonQuery(sql);
    }
    catch (System.Data.SQLite.SQLiteException e)
    {
        _log.Warn(e, string.Format("Failed to create column [{0}]. Most likely it already exists, which is fine.", columnName));
    }
}






alter-table