web-dev-qa-db-fra.com

Impossible d'ouvrir le fichier de base de données (code 14) avec la requête "SELECT" fréquente

J'ai la classe "Singleton" suivante pour gérer la connexion SQLite et m'assurer de disposer d'une instance de connexion pour l'ensemble du processus/de l'application:

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

Et la classe DBHelper elle-même:

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

Lorsque je fréquemment essaie de "SÉLECTIONNER" certaines informations de la base de données, le message d'erreur suivant s'affiche:

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)

J'exécute le code suivant pour exécuter la requête:

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
}

Comment puis-je gérer/améliorer ma connexion à la base de données pour surmonter/éviter ce problème?

7
JavaMachine

avant d'exécuter une requête à ce sujet (vous devez ouvrir votre base de données). Fermez la base de données une fois la tâche terminée.

private DBHelper dbHelper = new DBHelper(context);

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

// Ensuite, écrivez votre requête maintenant .... et fermez la base de données.

_db.close();

Vous pouvez consulter mon git link1git link2

11
Md. Shahadat Sarker

En outre, j’estime qu’un trop grand nombre de curseurs, et donc d’ouvrants, peut également entraîner le même problème "impossible d’ouvrir le fichier de base de données". (dans le code suivant, il y a 507 lignes dans leshoplistcursor, donc c'était terminé 1500 curseurs utilisés/réutilisés au total

Je recevais le même message. Selon: -

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

Le code, qui était en erreur, était: -

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

Le remède était de fermer les curseurs à chaque itération. Selon: -

 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();
    }
6
MikeT

J'utilise le curseur pour une grosse requête où le curseur a touché la base de données plus de 1350 fois par trois "QUERY" séparés dans un délai de 800 millisecondes. Alors j'ai eu l'erreur (Android.database.sqlite.SQLiteCantOpenDatabaseException: impossible d'ouvrir le fichier de base de données (code 14)). Je l'ai résolu en fermant le curseur avant de lancer une nouvelle requête. Cela résout mon problème. J'espère que cela fonctionnera plus gros que le mien.

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();
2
Sankha Pattanayak

Votre code rouvre la base de données à chaque appel de dbOpen().

Un objet de base de données SQLite est assez léger; ça n'a pas vraiment de sens de continuer à fermer et à rouvrir.

Vous avez déjà votre singleton; stockez-y simplement une référence SQLiteDatabase.

2
CL.