Android 当列明显存在时,SQlite 使用 getColumnIndex 返回 -1
Android SQlite returning -1 with getColumnIndex when column obviously exists
向我的 table 中的所有列插入临时值时,它似乎有效。请参阅下面的方法并在下面记录。但是当我用下面的测试方法测试该列是否存在时,returns该列存在是错误的!!
第一段代码显示从何处调用临时值和测试列是否存在的方法。下面的片段包括日志、table 的创建方式以及调用的方法。谢谢!
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
Table创建方法:
//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);
}
有
cursor.moveToFirst();
int value = cursor.getColumnIndex(myColumn);
您假设 PRAGMA
会将所有列 return 放在一行中。现在就是这样运作的。来自 PRAGMA
文档
PRAGMA table_info returns one row for each column in the named table. Columns in the result set include the column name, data type, whether or not the column can be NULL, and the default value for the column.
所以,您的 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
s。
来自 SQLite 文档:
PRAGMA table_info(table-name);
This pragma returns one row for each column in the named table.
因此您的 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 |
|-------------------------------------------------------
.......
|-------------------------------------------------------
向我的 table 中的所有列插入临时值时,它似乎有效。请参阅下面的方法并在下面记录。但是当我用下面的测试方法测试该列是否存在时,returns该列存在是错误的!!
第一段代码显示从何处调用临时值和测试列是否存在的方法。下面的片段包括日志、table 的创建方式以及调用的方法。谢谢!
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
Table创建方法:
//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);
}
有
cursor.moveToFirst();
int value = cursor.getColumnIndex(myColumn);
您假设 PRAGMA
会将所有列 return 放在一行中。现在就是这样运作的。来自 PRAGMA
文档
PRAGMA table_info returns one row for each column in the named table. Columns in the result set include the column name, data type, whether or not the column can be NULL, and the default value for the column.
所以,您的 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
s。
来自 SQLite 文档:
PRAGMA table_info(table-name);
This pragma returns one row for each column in the named table.
因此您的 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 |
|-------------------------------------------------------
.......
|-------------------------------------------------------