ALTER TABLE ADD COLUMN IF NOT EXISTS in SQLite

前端 未结 14 1746
青春惊慌失措
青春惊慌失措 2020-11-28 08:45

We\'ve recently had the need to add columns to a few of our existing SQLite database tables. This can be done with ALTER TABLE ADD COLUMN. Of course, if the table has alre

相关标签:
14条回答
  • 2020-11-28 09:35

    I solve it in 2 queries. This is my Unity3D script using System.Data.SQLite.

    IDbCommand command = dbConnection.CreateCommand();
                command.CommandText = @"SELECT count(*) FROM pragma_table_info('Candidat') c WHERE c.name = 'BirthPlace'";
                IDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    try
                    {
                        if (int.TryParse(reader[0].ToString(), out int result))
                        {
                            if (result == 0)
                            {
                                command = dbConnection.CreateCommand();
                                command.CommandText = @"ALTER TABLE Candidat ADD COLUMN BirthPlace VARCHAR";
                                command.ExecuteNonQuery();
                                command.Dispose();
                            }
                        }
                    }
                    catch { throw; }
                }
    
    0 讨论(0)
  • 2020-11-28 09:36

    I have a 99% pure SQL method. The idea is to version your schema. You can do this in two ways:

    • Use the 'user_version' pragma command (PRAGMA user_version) to store an incremental number for your database schema version.

    • Store your version number in your own defined table.

    In this way, when the software is started, it can check the database schema and, if needed, run your ALTER TABLE query, then increment the stored version. This is by far better than attempting various updates "blind", especially if your database grows and changes a few times over the years.

    0 讨论(0)
  • 2020-11-28 09:39

    SQLite also supports a pragma statement called "table_info" which returns one row per column in a table with the name of the column (and other information about the column). You could use this in a query to check for the missing column, and if not present alter the table.

    PRAGMA table_info(foo_table_name)
    

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

    0 讨论(0)
  • 2020-11-28 09:40

    For those want to use pragma table_info()'s result as part of a larger SQL.

    select count(*) from
    pragma_table_info('<table_name>')
    where name='<column_name>';
    
    

    The key part is to use pragma_table_info('<table_name>') instead of pragma table_info('<table_name>').


    This answer is inspired by @Robert Hawkey 's reply. The reason I post it as a new answer is I don't have enough reputation to post it as comment.

    0 讨论(0)
  • 2020-11-28 09:41

    I come up with this query

    SELECT CASE (SELECT count(*) FROM pragma_table_info(''product'') c WHERE c.name = ''purchaseCopy'') WHEN 0 THEN ALTER TABLE product ADD purchaseCopy BLOB END
    
    • Inner query will return 0 or 1 if column exists.
    • Based on the result, alter the column
    0 讨论(0)
  • 2020-11-28 09:43

    One workaround is to just create the columns and catch the exception/error that arise if the column already exist. When adding multiple columns, add them in separate ALTER TABLE statements so that one duplicate does not prevent the others from being created.

    With sqlite-net, we did something like this. It's not perfect, since we can't distinguish duplicate sqlite errors from other sqlite errors.

    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));
        }
    }
    
    0 讨论(0)
提交回复
热议问题