52

我需要检查一列是否存在,如果不存在则添加它。从我的研究来看,sqlite 似乎不支持 IF 语句,而应该使用 case 语句。

这是我到目前为止所拥有的:

SELECT CASE WHEN exists(select * from qaqc.columns where Name = "arg" and Object_ID = Object_ID("QAQC_Tasks")) = 0 THEN ALTER TABLE QAQC_Tasks ADD arg INT DEFAULT(0);

但我得到了错误:在“ALTER”附近:语法错误。

有任何想法吗?

4

15 回答 15

60

你不能使用ALTER TABLE with案例.

您正在寻找获取表的列名::-

PRAGMA table_info(table-name);

在PRAGMA上查看本教程

此编译指示为命名表中的每一列返回一行。结果集中的列包括列名、数据类型、列是否可以为 NULL,以及列的默认值。对于不属于主键的列,结果集中的“pk”列为零,对于属于主键的列,它是主键中的列的索引。

于 2013-09-20T15:10:58.753 回答
30

虽然这是一个老问题,但我在PRAGMA 函数中发现了一个更简单的解决方案:

SELECT COUNT(*) AS CNTREC FROM pragma_table_info('tablename') WHERE name='column_name'

如果结果大于零,则该列存在。简单的一行查询

诀窍是使用

pragma_table_info('tablename')

代替

PRAGMA table_info(tablename)

编辑:请注意,如PRAGMA 函数中所述:

此功能是实验性的,可能会发生变化。如果正式支持 PRAGMAs 功能的表值函数,则将提供进一步的文档。

在 SQLite 版本 3.16.0 (2017-01-02) 中添加了 PRAGMA 功能的表值函数。SQLite 的早期版本无法使用此功能。

于 2017-09-20T10:00:39.803 回答
18
// This method will check if column exists in your table
public boolean isFieldExist(String tableName, String fieldName)
{
     boolean isExist = false;
     SQLiteDatabase db = this.getWritableDatabase();
     Cursor res = db.rawQuery("PRAGMA table_info("+tableName+")",null);
    res.moveToFirst();
    do {
        String currentColumn = res.getString(1);
        if (currentColumn.equals(fieldName)) {
            isExist = true;
        }
    } while (res.moveToNext());
     return isExist;
}
于 2015-01-26T08:07:24.197 回答
6

您没有指定语言,因此假设它不是纯 sql,您可以检查列查询的错误:

SELECT col FROM table;

如果您收到错误,因此您知道该列不存在(假设您知道该表存在,无论如何您对此都有“IF NOT EXISTS”),否则该列存在,然后您可以相应地更改该表。

于 2013-12-02T10:40:06.890 回答
6

我已经应用了这个解决方案:

public boolean isFieldExist(SQLiteDatabase db, String tableName, String fieldName)
    {
        boolean isExist = false;

        Cursor res = null;

        try {

            res = db.rawQuery("Select * from "+ tableName +" limit 1", null);

            int colIndex = res.getColumnIndex(fieldName);
            if (colIndex!=-1){
                isExist = true;
            }

        } catch (Exception e) {
        } finally {
            try { if (res !=null){ res.close(); } } catch (Exception e1) {}
        }

        return isExist;
    }

它是 Pankaj Jangid 的代码变体。

于 2015-08-25T14:49:22.610 回答
4

检查现有列的一种奇怪方法

public static bool SqliteColumnExists(this SQLiteCommand cmd, string table, string column)
{
    lock (cmd.Connection)
    {
        // make sure table exists
        cmd.CommandText = string.Format("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '{0}'", table);
        var reader = cmd.ExecuteReader();

        if (reader.Read())
        {
            //does column exists?
            bool hascol = reader.GetString(0).Contains(String.Format("\"{0}\"", column));
            reader.Close();
            return hascol;
        }
        reader.Close();
        return false;
    }
}
于 2013-10-09T21:45:34.677 回答
3

要获取表的列名:

PRAGMA table_info (tableName);

要获取索引列:

PRAGMA index_info (indexName);
于 2013-09-20T15:14:56.480 回答
3

与 try、catch 和 finally 一起用于任何 rawQuery() 执行以获得更好的实践。下面的代码会给你结果。

public boolean isColumnExist(String tableName, String columnName)
{
    boolean isExist = false;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = null;
    try {
        cursor = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);
        if (cursor.moveToFirst()) {
            do {
                String currentColumn = cursor.getString(cursor.getColumnIndex("name"));
                if (currentColumn.equals(columnName)) {
                    isExist = true;
                }
            } while (cursor.moveToNext());

        }
    }catch (Exception ex)
    {
        Log.e(TAG, "isColumnExist: "+ex.getMessage(),ex );
    }
    finally {
        if (cursor != null)
            cursor.close();
        db.close();
    }
    return isExist;
}
于 2019-09-26T11:56:17.853 回答
2

更新 DATABASE_VERSION 以便调用 onUpgrade 函数,然后如果 Column 已经存在,那么如果不存在则不会发生任何事情,那么它将添加新列。

 private static class OpenHelper extends SQLiteOpenHelper {

OpenHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {


    if (!isColumnExists(db, "YourTableName", "YourColumnName")) {

        try {

            String sql = "ALTER TABLE " + "YourTableName" + " ADD COLUMN " + "YourColumnName" + "TEXT";
            db.execSQL(sql);

        } catch (Exception localException) {
            db.close();
        }

    }


}

}

 public static boolean isColumnExists(SQLiteDatabase sqliteDatabase,
                                     String tableName,
                                     String columnToFind) {
    Cursor cursor = null;

    try {
        cursor = sqliteDatabase.rawQuery(
                "PRAGMA table_info(" + tableName + ")",
                null
        );

        int nameColumnIndex = cursor.getColumnIndexOrThrow("name");

        while (cursor.moveToNext()) {
            String name = cursor.getString(nameColumnIndex);

            if (name.equals(columnToFind)) {
                return true;
            }
        }

        return false;
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}
于 2017-09-20T06:11:00.120 回答
2
SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');

..注意不完美的 LIKE 条件,但它对我有用,因为我所有的列都有非常独特的名称..

于 2019-11-29T13:40:51.647 回答
1

IF与SQLite类似,CASE在 SQLite 中是一个表达式。你不能ALTER TABLE和它一起使用。见:http ://www.sqlite.org/lang_expr.html

于 2013-09-20T15:11:51.540 回答
0
  public static bool columExsist(string table, string column)
    {
        string dbPath = Path.Combine(Util.ApplicationDirectory, "LocalStorage.db");

        connection = new SqliteConnection("Data Source=" + dbPath);
        connection.Open();

        DataTable ColsTable = connection.GetSchema("Columns");

        connection.Close();

        var data = ColsTable.Select(string.Format("COLUMN_NAME='{1}' AND TABLE_NAME='{0}1'", table, column));

        return data.Length == 1;
    }
于 2014-12-23T11:32:54.647 回答
0

我更新了一个朋友的功能......现在已经测试和工作了

    public boolean isFieldExist(String tableName, String fieldName)
{
    boolean isExist = false;
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor res = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);


    if (res.moveToFirst()) {
        do {
            int value = res.getColumnIndex("name");
            if(value != -1 && res.getString(value).equals(fieldName))
            {
                isExist = true;
            }
            // Add book to books

        } while (res.moveToNext());
    }

    return isExist;
}
于 2016-01-27T15:33:06.907 回答
0

我真的很抱歉迟到了。发帖的意图可能对某人的情况有所帮助。

我尝试从数据库中获取列。如果它返回一行,则它包含该列,否则不...

-(BOOL)columnExists { 
 BOOL columnExists = NO;

//Retrieve the values of database
const char *dbpath = [[self DatabasePath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){

    NSString *querySQL = [NSString stringWithFormat:@"SELECT lol_10 FROM EmployeeInfo"];
    const char *query_stmt = [querySQL UTF8String];

    int rc = sqlite3_prepare_v2(database ,query_stmt , -1, &statement, NULL);
    if (rc  == SQLITE_OK){
        while (sqlite3_step(statement) == SQLITE_ROW){

            //Column exists
            columnExists = YES;
            break;

        }
        sqlite3_finalize(statement);

    }else{
        //Something went wrong.

    }
    sqlite3_close(database);
}

return columnExists; 
}
于 2016-03-21T10:57:53.400 回答
0

其中一些示例对我不起作用。我正在尝试检查我的表是否已经包含一列。

我正在使用这个片段:

public boolean tableHasColumn(SQLiteDatabase db, String tableName, String columnName) {
    boolean isExist = false;
    Cursor cursor = db.rawQuery("PRAGMA table_info("+tableName+")",null);
    int cursorCount = cursor.getCount();
    for (int i = 1; i < cursorCount; i++ ) {
        cursor.moveToPosition(i);
        String storedSqlColumnName = cursor.getString(cursor.getColumnIndex("name"));
        if (columnName.equals(storedSqlColumnName)) {
            isExist = true;
        }
    }
    return isExist;
}

上面的示例是查询作为元数据表而不是实际数据的 pragma 表,每列指示名称、类型和有关表列的一些其他内容。所以实际的列名在行内。

希望这对其他人有帮助。

于 2017-11-16T16:43:39.960 回答