代码之家  ›  专栏  ›  技术社区  ›  Herrozerro

检查SQLite中是否存在列

  •  61
  • Herrozerro  · 技术社区  · 13 年前

    我需要检查列是否存在,如果不存在,请添加它。根据我的研究,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”:语法错误。

    有什么想法吗?

    17 回复  |  直到 13 年前
        1
  •  66
  •   Rahul Tripathi    13 年前

    您不能使用 ALTER TABLE with 案例 .

    您正在查找表的列名:-

    PRAGMA table_info(table-name);
    

    查看上的本教程 PRAGMA

    此杂注为命名表中的每列返回一行。 结果集中的列包括列名、数据类型、 该列是否可以为NULL,以及该列的默认值。 对于不是的列,结果集中的“pk”列为零 主键的一部分,并且是主键中列的索引 作为主键一部分的列的键。

        2
  •  39
  •   Formentz    4 年前

    尽管这是一个老问题,但我在 PRAGMA functions 一个更简单的解决方案:

    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无法使用此功能

        3
  •  18
  •   Yury Lvov Pankaj Jangid    8 年前
    // 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;
    }
    
        4
  •  6
  •   Niki Romagnoli    12 年前

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

    SELECT col FROM table;
    

    如果您得到一个错误,所以您知道该列不在那里(假设您知道该表存在,无论如何您对此有“if not exists”),否则该列存在,然后您可以相应地更改该表。

        5
  •  6
  •   Jason D    11 年前

    我已应用此解决方案:

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

        6
  •  5
  •   Guru raj    7 年前

    使用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;
    }
    
        7
  •  4
  •   Parimal Raj    13 年前

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

    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;
        }
    }
    
        8
  •  4
  •   Jaro B    6 年前
    SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');
    

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

        9
  •  3
  •   Oleksandr Pyrohov Andreas    9 年前

    要获取表的列名,请执行以下操作:

    PRAGMA table_info (tableName);
    

    要获取索引列,请执行以下操作:

    PRAGMA index_info (indexName);
    
        10
  •  3
  •   JarTap    4 年前

    我使用了以下内容 SELECT 带有SQLite 3.13.0的语句

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

    如果列为,则返回0(零) <column_name> 表中不存在 <table_name> .

        11
  •  2
  •   jakir hussain    9 年前

    更新DATABASE_VERSION,以便调用Upgrade函数,然后如果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();
            }
        }
    }
    
        12
  •  1
  •   Colonel Thirty Two    13 年前

    类似 IF 在SQLite中, CASE 在SQLite中是 表示 。你不能使用 ALTER TABLE 使用它。请参阅: http://www.sqlite.org/lang_expr.html

        13
  •  1
  •   andrey2ag    10 年前

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

        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;
    }
    
        14
  •  1
  •   Abdul Yasin    10 年前

    我真的很抱歉发晚了。在某人的情况下,以的意图发布可能会有所帮助。

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

    -(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; 
    }
    
        15
  •  0
  •   Claus Elmann    11 年前
      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;
        }
    
        16
  •  0
  •   4gus71n    8 年前

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

    我正在使用以下片段:

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

    希望这能帮助到其他人。

        17
  •  0
  •   buddemat nerdWannabe    4 年前
    SELECT INSTR(Lower(sql), " exceptionclass ") FROM sqlite_master WHERE type="table" AND Lower(name)="bugsgroup";
    
    推荐文章