检查 SQLite 中是否存在列

问题描述 投票:0回答:18

我需要检查列是否存在,如果不存在则添加它。根据我的研究,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);

但我收到错误:Near“ALTER”:语法错误。

有什么想法吗?

sqlite
18个回答
67
投票

您不能使用

ALTER TABLE with
case
.

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

PRAGMA table_info(table-name);

PRAGMA

上查看本教程

此编译指示为指定表中的每一列返回一行。 结果集中的列包括列名、数据类型、是否 或不该列可以为NULL,并为该列的默认值。 对于不存在的列,结果集中的“pk”列为零 主键的一部分,是主键中列的索引 作为主键一部分的列的键。


46
投票

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

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

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

秘诀就是使用

pragma_table_info('tablename')

而不是

PRAGMA table_info(tablename)

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

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


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;
}

7
投票

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

SELECT col FROM table;

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


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 的代码变体。


5
投票

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

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;
}

5
投票
SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');

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


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;
    }
}

3
投票

获取表的列名称:

PRAGMA table_info (tableName);

要获取索引列:

PRAGMA index_info (indexName);

3
投票

我在 SQLite 3.13.0 中使用了以下

SELECT
语句

SELECT INSTR(sql, '<column_name>') FROM sqlite_master WHERE type='table' AND name='<table_name>';

如果表

<column_name>
中不存在列
<table_name>
,则返回 0(零)。


2
投票

我更新了朋友的功能...已测试并正在工作

    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;
}

2
投票

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

 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();
        }
    }
}

1
投票

与 SQLite 中的

IF
类似,SQLite 中的
CASE
是一个 表达式。您不能将
ALTER TABLE
与它一起使用。请参阅:http://www.sqlite.org/lang_expr.html


1
投票

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

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

-(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; 
}

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;
    }

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 表,它是一个元数据表,而不是实际数据,每一列表示名称、类型和有关表列的一些其他内容。因此实际的列名称位于行内。

希望这对其他人有帮助。


0
投票
SELECT INSTR(Lower(sql), " exceptionclass ") FROM sqlite_master WHERE type="table" AND Lower(name)="bugsgroup";

0
投票
Select * FROM pragma_table_xinfo('my table') WHERE lower(name) = 'myCol';
© www.soinside.com 2019 - 2024. All rights reserved.