SQLite unable to open database file (code 14) on frequent “SELECT” query

岁酱吖の 提交于 2020-01-09 19:33:55

问题


I have following class "Singleton" to handle SQLite connection and to make sure to have 1 instance of connection for whole process/app:

public class DBController {
  private static DBController instance = new DBController();
  private static DBHelper dbHelper;
  public static DBController getInstance()
  {
    return instance;
  }
  public SQLiteDatabase dbOpen(Context context)
  {
    if(dbHelper == null)
        dbHelper = new DBHelper(context);
    return dbHelper.getWritableDatabase();
  }
}

And DBHelper class itself:

public class DBHelper extends SQLiteOpenHelper {

  public DBHelper(Context context) {
    super(context, "database.db", null, 1);
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
    final String position = "CREATE TABLE test (" +
            "test TEXT NOT NULL);";
    db.execSQL(position);
  }
}

When I frequently try to "SELECT" some info from database I am receiving following error:

SQLiteLog: (14) cannot open file at line 31278 of [2ef4f3a5b1]
SQLiteLog: (14) os_unix.c:31278: (24) open(/data/user/0/uz.mycompany.myapp/databases/database.db-journal) - 
SQLiteLog: (14) cannot open file at line 31278 of [2ef4f3a5b1]
SQLiteLog: (14) os_unix.c:31278: (24) open(/data/user/0/uz.mycompany.myapp/databases/database.db-journal) - 
SQLiteLog: (14) statement aborts at 29: [SELECT * FROM test WHERE test='testdata1'] unable to open database file
SQLiteQuery: exception: unable to open database file (code 14); query: SELECT * FROM test WHERE test='testdata1'
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)

I am running following code to execute query:

public String getData(Context context)
{
    SQLiteDatabase _db = dbOpen(context);
    Cursor c = _db.rawQuery("SELECT * FROM test WHERE test='testdata1'", null);
    return getDataFromCursor(c).get(0); //gets data from cursor and returns first one
}

How can I manage/improve my database connection to overcome/avoid this problem?


回答1:


before executing any query to this stuff (You should open your database). Close db after completion the task.

private DBHelper dbHelper = new DBHelper(context);

try {
    _db = dbHelper.getWritableDatabase();
} catch (SQLException s) {
    new Exception("Error with DB Open");
}

// Then write your query now.... and then close the db.

_db.close();

You can check out my git link1 git link2




回答2:


As an addition, I believe that having too many cursors, and thus open's, can also result in the same "unable to open database file error". (in the following code, there's 507 rows in the shoplistcursor, so that was over 1500 cursors used/reused in total)

I was getting the same message. As per :-

10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) os_unix.c:30046: (24) open(/data/data/mjt.shopper/databases/Shopper-journal) - 
10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) cannot open file at line 30046 of [9491ba7d73]
10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) os_unix.c:30046: (24) open(/data/data/mjt.shopper/databases/Shopper-journal) - 
10-29 19:57:00.901 12845-12845/mjt.shopper E/SQLiteLog: (14) statement aborts at 24: [SELECT *  FROM productusage WHERE productailseref = 60 AND productproductref = 75 ;] unable to open database file
10-29 19:57:00.902 12845-12845/mjt.shopper E/SQLiteQuery: exception: unable to open database file (code 14); query: SELECT *  FROM productusage WHERE productailseref = 60 AND productproductref = 75 ;
10-29 19:57:00.902 12845-12845/mjt.shopper D/AndroidRuntime: Shutting down VM
10-29 19:57:00.903 12845-12845/mjt.shopper E/AndroidRuntime: FATAL EXCEPTION: main

The code, that was in error, was :-

 SQLiteDatabase db = getWritableDatabase();
        Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
        Cursor productcsr;
        Cursor aislecsr;
        Cursor prdusecsr;
        while(shoplistcursor.moveToNext()) {
            productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
            prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                    shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
            } 
            if(shoplistcursor.isLast()) {
                prdusecsr.close();
                aislecsr.close();
                productcsr.close();
            }
        }
        shoplistcursor.close();
        db.close();
}

The cure was to close the cursors on each iteration. As per :-

 SQLiteDatabase db = getWritableDatabase();
        Cursor shoplistcursor = getAllRowsFromTable(SHOPLIST_TABLE_NAME);
        Cursor productcsr;
        Cursor aislecsr;
        Cursor prdusecsr;
        while(shoplistcursor.moveToNext()) {
            productcsr = getProductFromProductId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            aislecsr = getAisleFromAisleId(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)));
            prdusecsr = getProductUsage(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_AISLEREF)),
                    shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_PRODUCTREF)));
            if (productcsr.getCount() < 1 | aislecsr.getCount() < 1 | prdusecsr.getCount() < 1) {
                productcsr.close();
                aislecsr.close();
                prdusecsr.close();
                deleteShopListEntry(shoplistcursor.getLong(shoplistcursor.getColumnIndex(SHOPLIST_COLUMN_ID)));
            } else {
                productcsr.close();
                aislecsr.close();
                prdusecsr.close();
            }
        }
        shoplistcursor.close();
        db.close();
    }



回答3:


Your code re-opens the database every time dbOpen() is called.

An SQLite database object is quite lightweight; it does not really make sense to keep closing and re-opening it.

You already have your singleton; just store a single SQLiteDatabase reference there.




回答4:


I am using cursor for a big query where cursor hit the DB more than 1350 times by three seperate 'QUERY' within 800 milliseconds. So I got the error (android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)). I solved it by closing the cursor before start a new query. That resolves my problem. Hope it will work the more big query than mine.

String data_query = "SELECT * FROM test WHERE id= " + c_id + " AND memberId = " + memberId;           
Cursor cu_cu = userHelper.getData(data_query);
float cu_cu_count = cu_cu.getCount();
System.out.println("ALL ANSWER COUNT : " + cu_cu_count);
cu_cu.close();


来源:https://stackoverflow.com/questions/35008632/sqlite-unable-to-open-database-file-code-14-on-frequent-select-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!