Android的SQLite的返回-1,getColumnIndex列时存在明显明显、存在、Android、SQLite

2023-09-06 22:40:52 作者:子夜笙歌落

当我在表中插入临时值到所有的列,它似乎工作。请参阅下面的方法和下面登录。但是,当我测试,如果列存在,我在下面的测试方法,该列存在返回false !!

的code中的第一个片段展示了从那里临时值和方法,如果某列存在的测试被调用。下面的代码片段包括日志,如何创建表,并调用的方法。谢谢!

  ContentValues​​值= setContVal_All_Columns(myTable的);

//创建一行
长insertId = database.insert(myTable的,空,价值观);
的System.out.println(列日存在=+将String.valueOf(doesColumnExist(myTable的,日)));
 

setContVal_All_Columns方法:

  //设置通用内容值初始化行=不包括ID列
私人ContentValues​​ setContVal_All_Columns(字符串myTable的){

    ContentValues​​ contentValues​​ =新ContentValues​​();
    光标光标= database.query(myTable的,NULL,NULL,NULL,NULL,NULL,NULL);
    的String [] columnNames = cursor.getColumnNames();
    cursor.moveToFirst();

    对于(字符串名称:columnNames){
        如果(!name.equals(IdColumn)){//排除Id列
            INT指数= cursor.getColumnIndex(名称);
            的System.out.println(列名=+姓名+指数=+将String.valueOf(指数));
            的System.out.println(类型=+将String.valueOf(cursor.getType(索引))); //出现崩溃的的getType
            如果(cursor.getType(指数)== 3){//串
                的System.out.println(栏中的字符串);
                contentValues​​.put(姓名,);
            }否则,如果(cursor.getType(指数)== 1){//整数
                contentValues​​.put(姓名,0);
            }
        }
    }

    返回contentValues​​;
}
 

方法进行测试如果列同时存在:总是返回-1日期列...

 私人布尔doesColumnExist(字符串myTable的,字符串根据MyColumn){
    布尔doesExist = TRUE;

光标光标= database.rawQuery(杂table_info(+为myTable +),NULL);
cursor.moveToFirst();

int值= cursor.getColumnIndex(根据MyColumn);

如果(价值== -1)
{
    doesExist = FALSE;
}
返回doesExist;
}
 

日志信息:

  02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列名=日期索引= 1
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders I / System.out的:类型= 0
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列名=名称指数= 2
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders I / System.out的:类型= 3
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列是字符串
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列名=海拔指数= 3
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders I / System.out的:类型= 0
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列名= is_used指数= 4
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders I / System.out的:类型= 0
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列名=预警指数= 5
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders I / System.out的:类型= 0
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列名=动作指数= 6
02-16 19:58:42.296 9711-9711 / com.mycompany.dudesmyreminders I / System.out的:类型= 0
02-16 19:58:42.316 9711-9711 / com.mycompany.dudesmyreminders我/的System.out:列日存在=假
 

表创建方法:

  //数据库创建SQL语句
私有静态最后弦乐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 +
                //任何其他选项CREATE命令
                );



@覆盖
公共无效的onCreate(SQLiteDatabase数据库){
    database.execSQL(SQL_CREATE_SPECIAL_DAYS);
}

@覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
    Log.w(MySQLiteHelper.class.getName(),
            + oldVersion +到从版本升级数据库
                    +动态网页+,这将销毁所有旧数据);
    db.execSQL(DROP TABLE IF EXISTS+ dbFields.TABLE_NAME_SPECIAL_DAYS);
    的onCreate(DB);
}
 

解决方案

通过

  cursor.moveToFirst();
int值= cursor.getColumnIndex(根据MyColumn);
 

您正在假定 PRAGMA 将返回所有列在一行。这就是现在它是如何工作的。从 PRAGMA 文件

  

PRAGMA table_info返回一行每列在指定的表。列结果集中包含的列名,数据类型,列是否可以为NULL,和该​​列的默认值。

那么,你的 doesColumnExist()的方法应该是这个样子

 布尔doesExist = FALSE;
光标光标= database.rawQuery(杂table_info(+为myTable +),NULL);

而(cursor.moveToNext()){
    如果(cursor.getString(cursor.getColumnIndex(名字))。等于(根据MyColumn)){
        doesExist = TRUE;
        打破;
    }
}

cursor.close();
返回doesExist;
 

另外,不要忘了关闭光标秒。

When inserting temporary values to all of the columns in my table, it appears to work. See method below and log below. But when I test if the column exists with my test method below, it returns a false that the column exists!!

The first snippet of code shows from where the temporary values and the method for testing if a column exists is called. The snippets below include the log, how the table is created, and the called methods. Thank you!

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 Method:

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

METHOD FOR TESTING IF COLUMN EXISTS: always returning -1 on date column...

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

LOG INFO:

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 Creation Method:

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

解决方案

With

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

You're assuming that PRAGMA would return all the columns in a single row. That's now how it works. From the PRAGMA documentation

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.

So, your doesColumnExist() method should look something like

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;

Also, do not forget to close your Cursors.