当列显然存在时,Android SQlite使用getColumnIndex返回-1

时间:2015-02-17 04:44:33

标签: android mysql sqlite

将临时值插入表格中的所有列时,它似乎有效。请参阅以下方法并在下面记录。但是,当我测试列是否存在下面的测试方法时,它会返回false,表示该列存在!!

第一段代码显示调用临时值和测试列是否存在的方法。下面的代码段包括日志,表的创建方式以及调用的方法。谢谢!

ContentValues values = setContVal_All_Columns(myTable);

//create row
long insertId = database.insert(myTable, null, values);
System.out.println("Column date exists = " + String.valueOf(doesColumnExist(myTable,"date")));

setContVal_All_Columns方法:

//sets generic content values to initialize row = excluding ID column
private ContentValues setContVal_All_Columns(String myTable) {

    ContentValues contentValues = new ContentValues();
    Cursor cursor = database.query(myTable,null,null,null,null,null,null);
    String[] columnNames = cursor.getColumnNames();
    cursor.moveToFirst();

    for(String name : columnNames) {
        if(!name.equals(IdColumn)) {  //excludes Id column
            int index = cursor.getColumnIndex(name);
            System.out.println("Column name = " + name + " index = " + String.valueOf(index));
            System.out.println("Type = " + String.valueOf(cursor.getType(index))); //appears to crash on the getType
            if (cursor.getType(index) == 3) {  //String
                System.out.println("Column is string");
                contentValues.put(name, " ");
            } else if (cursor.getType(index) == 1) {  //integer
                contentValues.put(name, 0);
            }
        }
    }

    return contentValues;
}

测试如果列存在的方法:总是在日期列上返回-1 ...

private boolean doesColumnExist(String myTable, String myColumn) {
    boolean doesExist = true;

Cursor cursor = database.rawQuery("PRAGMA table_info(" + myTable + ")",null);
cursor.moveToFirst();

int value = cursor.getColumnIndex(myColumn);

if(value == -1)
{
    doesExist = false;
}
return doesExist;
}

日志信息:

02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column name = date index = 1
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Type = 0
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column name = name index = 2
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Type = 3
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column is string
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column name = altitude index = 3
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Type = 0
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column name = is_used index = 4
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Type = 0
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column name = warning index = 5
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Type = 0
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column name = action index = 6
02-16 19:58:42.296    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Type = 0
02-16 19:58:42.316    9711-9711/com.mycompany.dudesmyreminders I/System.out﹕ Column date exists = false

表格创建方法:

//Database creation sql statement
private static final String SQL_CREATE_SPECIAL_DAYS =
        "CREATE TABLE " + dbFields.TABLE_NAME_SPECIAL_DAYS + " (" +
                dbFields.COLUMN_SPECIAL_DAYS_ID + INTEGER_PRIMARY_KEY + COMMA_SEP +
                dbFields.COLUMN_SPECIAL_DAYS_DATE + TEXT_TYPE + COMMA_SEP +
                dbFields.COLUMN_SPECIAL_DAYS_NAME + TEXT_TYPE + COMMA_SEP +
                dbFields.COLUMN_SPECIAL_DAYS_ALTITUDE + INTEGER_TYPE + COMMA_SEP +
                dbFields.COLUMN_SPECIAL_DAYS_USED + INTEGER_TYPE + COMMA_SEP +
                dbFields.COLUMN_SPECIAL_DAYS_WARNING + INTEGER_TYPE + COMMA_SEP +
                dbFields.COLUMN_SPECIAL_DAYS_ACTION + INTEGER_TYPE +
                // Any other options for the CREATE command
                " )";



@Override
public void onCreate(SQLiteDatabase database) {
    database.execSQL(SQL_CREATE_SPECIAL_DAYS);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    Log.w(MySQLiteHelper.class.getName(),
            "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
    db.execSQL("DROP TABLE IF EXISTS " + dbFields.TABLE_NAME_SPECIAL_DAYS);
    onCreate(db);
}

2 个答案:

答案 0 :(得分:3)

使用

cursor.moveToFirst();
int value = cursor.getColumnIndex(myColumn);

您假设PRAGMA将返回单行中的所有列。现在它是如何运作的。来自PRAGMA文档

  

PRAGMA table_info在命名表中为每列返回一行。结果集中的列包括列名,数据类型,列是否为NULL以及列的默认值。

因此,您的doesColumnExist()方法应该类似于

boolean doesExist = false;
Cursor cursor = database.rawQuery("PRAGMA table_info(" + myTable + ")",null);

while (cursor.moveToNext()) {
    if (cursor.getString(cursor.getColumnIndex("name")).equals(myColumn)) {
        doesExist = true;
        break;
    }
}

cursor.close();
return doesExist;

此外,请不要忘记关闭Cursor

答案 1 :(得分:2)

来自SQLite文档:

  

PRAGMA table_info(table-name);
  该pragma在命名表中为每列返回一行

因此PRAGMA查询的结果大致如下:

|-------------------------------------------------------
|cid | name     | type    | not null | dflt_value | pk |   // <-- you're trying to find your column names here, but instead they are in each of the rows
|-------------------------------------------------------
| 1  | date     | text    | 1        |            | 0  |
|-------------------------------------------------------
| 2  | name     | text    | 0        |            | 0  | 
|-------------------------------------------------------
| 3  | altitude | integer | 1        |            | 0  |
|-------------------------------------------------------
  .......                                              
|-------------------------------------------------------