【问题标题】:cursor iterate over null row游标遍历空行
【发布时间】:2018-05-11 22:42:32
【问题描述】:

我的游标和数据库有问题,如果我使用 !cursor.isAfterLast() 一段时间,在实际非空行之后,我启动应用程序的次数与我启动应用程序的次数一样多(并放了一个行中的值)

这是我的代码:

public class DatabaseCreator extends SQLiteOpenHelper {
    // Database Version
    private static final int DATABASE_VERSION = 1;

    // Database Name
    private static final String DATABASE_NAME_WITH_EXTENSION = "drawinguess_local_database.db";

    // Table Names
    public static final String DB_TABLE = "image_bmp";

    // column names
    private static final String COLUMN_ID = "_id";
    private static final String KEY_NAME = "image_title";
    private static final String KEY_AUTHOR = "image_author";
    private static final String KEY_IMAGE = "image_data";

    // Table create statement
    private static final String CREATE_TABLE_IMAGE = "CREATE TABLE " + DB_TABLE + "("+ COLUMN_ID + " integer primary key autoincrement, " + KEY_NAME + "  TEXT," + KEY_AUTHOR + " TEXT," + KEY_IMAGE + " BLOB);";

    public DatabaseCreator(Context context) {
        super(context, DATABASE_NAME_WITH_EXTENSION, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
        db.execSQL(CREATE_TABLE_IMAGE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // on upgrade drop older tables
        db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);

        // create new table
        onCreate(db);
    }

    public void addEntry(String title, String author, byte[] image) throws SQLiteException {
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues cv = new  ContentValues();
        cv.put(KEY_NAME,    title);
        cv.put(KEY_AUTHOR, author);
        cv.put(KEY_IMAGE,   image);
        database.insert( DB_TABLE, null, cv );
    }

    public void addEntry(String title, byte[] image) throws SQLiteException {
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues cv = new  ContentValues();
        cv.put(KEY_NAME,    title);
        cv.put(KEY_IMAGE,   image);
        database.insert( DB_TABLE, null, cv );
    }

    public void addEntry(byte[] image) throws SQLiteException {
        SQLiteDatabase database = this.getWritableDatabase();
        ContentValues cv = new  ContentValues();
        cv.put(KEY_IMAGE,   image);
        database.insert( DB_TABLE, null, cv );
    }

    public void updateLastTitle(String title) throws SQLiteException{
        SQLiteDatabase database = this.getWritableDatabase();
        String strSQL;

        //Cursor cursor = database.query(DATABASE_NAME, new String[]{"ID"}, null, null, null, null, null);
        Cursor cursor = database.rawQuery("SELECT "+ COLUMN_ID +" FROM " + DB_TABLE, null);
        cursor.moveToLast();

        strSQL = "UPDATE " + DB_TABLE + " SET "+ KEY_NAME + " = \"" + title +"\" WHERE "+ COLUMN_ID +" = "+ cursor.getColumnCount();

        database.execSQL(strSQL);
    }

    public List<TitledBitmap> getAllTitledBitmap() {
        SQLiteDatabase database = this.getReadableDatabase();
        List<TitledBitmap> titledBitmaps = new ArrayList<TitledBitmap>();

        Cursor cursor = database.query(DB_TABLE, new String[]{"image_title", "image_data"}, null, null, null, null, null);

        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            System.out.println("This is the title : " + cursor.getString(0));
            TitledBitmap titledBitmap = cursorToTitledBitmap(cursor);
            titledBitmaps.add(titledBitmap);
            cursor.moveToNext();
        }

        cursor.close();
        return titledBitmaps;
    }

    private TitledBitmap cursorToTitledBitmap(Cursor cursor) {
        TitledBitmap titledBitmap = new TitledBitmap();
        titledBitmap.setTitle(cursor.getString(0));
        titledBitmap.setByteArray(cursor.getBlob(1));
        return titledBitmap;
    }

}

问题出在 getAllTitledBitmap() 中,我猜,这要归功于 Syso 的输出:

I/System.out: This is the title : TheValueThatWorked
          This is the title : null
          This is the title : null

提前谢谢你 祝你有美好的一天

【问题讨论】:

  • 数据库中标题的可能性为空,我看不出有什么明显的错误。
  • 谢谢!我试图搜索原因,但我不知道,否则,我使用多个活动将数据写入数据库,但我只有最后一个条目工作,所有其他都是 null 我使用 DatabaseCreator db = new DatabaseCreator(this)我所有的活动,也许这搞砸了?
  • 重新评论 “我在所有活动中都使用 DatabaseCreator db = new DatabaseCreator(this),也许这搞砸了?”。不,这不会把事情搞砸,你应该这样做。

标签: android sql database sqlite loops


【解决方案1】:

您的问题是您在使用 addEntry 时仅使用了 byte[] 签名,而这并没有设置 Title,因此它将为 null。

使用 :-

测试您的代码
private void SO50301166() {
    DatabaseCreator dc = new DatabaseCreator(this);
    dc.addEntry("001 Added with author","Fred",new byte[]{0,1,2,3,4,5,6,7,8,9,0});
    dc.addEntry("002 Added",new byte[]{12,13,14,15,16,17,18,19,10});
    dc.addEntry(new byte[]{20,21,22,23,24,25,26,27,28,29,30});
    dc.getAllTitledBitmap();
}

结果:-

05-11 23:10:28.306 1283-1283/? I/System.out: This is the title : 001 Added with author
    This is the title : 002 Added
    This is the title : null

即使用dc.addEntry(new byte[]{20,21,22,23,24,25,26,27,28,29,30}); 不会设置标题,因此它将为空。

所以你可能想要改变:-

public void addEntry(byte[] image) throws SQLiteException {
    SQLiteDatabase database = this.getWritableDatabase();
    ContentValues cv = new  ContentValues();
    cv.put(KEY_IMAGE,   image);
    database.insert( DB_TABLE, null, cv );
}

成为:-

public void addEntry(byte[] image) throws SQLiteException {
    SQLiteDatabase database = this.getWritableDatabase();
    ContentValues cv = new  ContentValues();
    cv.put(KEY_IMAGE,   image);
    cv.put(KEY_NAME,"No Title Provided"); //<<<< ADDED
    database.insert( DB_TABLE, null, cv );
}

但是,您可以简化代码,并且使用 Author 也不会遇到同样的问题:-

public void addEntry(String title, String author, byte[] image) throws SQLiteException {
    SQLiteDatabase database = this.getWritableDatabase();
    ContentValues cv = new ContentValues();
    cv.put(KEY_NAME, title);
    cv.put(KEY_AUTHOR, author);
    cv.put(KEY_IMAGE, image);
    database.insert(DB_TABLE, null, cv);
}

public void addEntry(String title, byte[] image) throws SQLiteException {
    addEntry(title,"No Author Proivided", image);
}

public void addEntry(byte[] image) throws SQLiteException {
    addEntry("No Title Provided",image);
}

即主代码在最完整的签名中,较小的签名调用下一个更完整的签名。

使用它会导致(使用之前的测试用例):-

This is the title : 001 Added with author
This is the title : 002 Added
This is the title : No Title Provided

【讨论】:

  • 好吧,我明白你的意思了!谢谢你的帮助,我会试试这个
猜你喜欢
  • 1970-01-01
  • 2011-06-23
  • 2017-04-12
  • 1970-01-01
  • 1970-01-01
  • 2019-08-22
  • 2021-07-30
  • 2011-08-18
  • 1970-01-01
相关资源
最近更新 更多