Frage Wie überprüft man, ob eine Tabelle in einer Android SQLite-Datenbank existiert?


Ich habe eine Android-App, die prüfen muss, ob es bereits einen Datensatz in der Datenbank gibt, und wenn nicht, einige Dinge verarbeiten und schließlich einfügen, und einfach die Daten aus der Datenbank lesen, wenn die Daten existieren. Ich verwende eine Unterklasse von SQLiteOpenHelper, um eine wiederbeschreibbare Instanz von SQLiteDatabase zu erstellen und zu erhalten, von der ich dachte, dass sie automatisch für die Erstellung der Tabelle sorgte, wenn sie noch nicht existierte (da der Code dafür in onCreate (... ) Methode).

Wenn die Tabelle jedoch noch NICHT existiert und die erste Methode auf dem SQLiteDatabase-Objekt lief, das ich habe, ist ein Aufruf zur Abfrage (...), mein Logcat zeigt einen Fehler von "I / Database (26434): sqlite returned: error code = 1, msg = keine solche Tabelle: appdata ", und tatsächlich wird die appdata-Tabelle nicht erstellt.

Irgendwelche Ideen warum?

Ich suche nach einer Methode, um zu testen, ob die Tabelle existiert (denn wenn nicht, dann sind die Daten nicht drin und ich muss sie erst lesen, wenn ich sie schreibe, was die Tabelle zu erstellen scheint richtig, oder eine Möglichkeit, um sicherzustellen, dass es erstellt wird, und ist nur leer, rechtzeitig für den ersten Aufruf zur Abfrage (...)

BEARBEITEN
Dies wurde nach den zwei Antworten unten veröffentlicht:
Ich denke, ich habe das Problem gefunden. Ich entschied aus irgendeinem Grund, dass für jede Tabelle ein anderer SQLiteOpenHelper erstellt werden sollte, obwohl beide auf dieselbe Datenbankdatei zugreifen. Ich denke Refactoring dieses Codes, um nur einen OpenHelper zu verwenden, und das Erstellen beider Tabellen innerhalb von onCreate funktioniert möglicherweise besser ...


75
2018-06-17 04:40


Ursprung


Antworten:


Probier diese:

public boolean isTableExists(String tableName, boolean openDb) {
    if(openDb) {
        if(mDatabase == null || !mDatabase.isOpen()) {
            mDatabase = getReadableDatabase();
        }

        if(!mDatabase.isReadOnly()) {
            mDatabase.close();
            mDatabase = getReadableDatabase();
        }
    }

    Cursor cursor = mDatabase.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'", null);
    if(cursor!=null) {
        if(cursor.getCount()>0) {
                            cursor.close();
            return true;
        }
                    cursor.close();
    }
    return false;
}

113
2017-10-22 23:52



Ich weiß nichts über die Android SQLite-API, aber wenn Sie direkt in SQL mit ihm kommunizieren können, können Sie Folgendes tun:

create table if not exists mytable (col1 type, col2 type);

Dies stellt sicher, dass die Tabelle immer erstellt wird und keine Fehler wirft, wenn sie bereits existiert.


45
2018-06-17 04:47



Obwohl es bereits viele gute Antworten auf diese Frage gibt, habe ich eine andere Lösung gefunden, die meiner Meinung nach einfacher ist. Umgeben Sie Ihre Abfrage mit einem try Block und dem folgenden Catch:

catch (SQLiteException e){
    if (e.getMessage().contains("no such table")){
            Log.e(TAG, "Creating table " + TABLE_NAME + "because it doesn't exist!" );
            // create table
            // re-run query, etc.
    }
}

Es hat für mich funktioniert!


10
2017-08-15 09:07



Das habe ich gemacht:

/* open database, if doesn't exist, create it */
SQLiteDatabase mDatabase = openOrCreateDatabase("exampleDb.db", SQLiteDatabase.CREATE_IF_NECESSARY,null);

Cursor c = null;
boolean tableExists = false;
/* get cursor on it */
try
{
    c = mDatabase.query("tbl_example", null,
        null, null, null, null, null);
        tableExists = true;
}
catch (Exception e) {
    /* fail */
    Log.d(TAG, tblNameIn+" doesn't exist :(((");
}

return tableExists;

9
2017-09-21 19:01



Yep, stellt sich heraus, dass die Theorie in meiner Bearbeitung richtig war: Das Problem, das die OnCreate-Methode nicht ausgeführt wurde, war die Tatsache, dass SQLiteOpenHelper Objekte sollten sich auf Datenbanken beziehen und nicht für jede Tabelle eine eigene haben. Packen Sie beide Tabellen zu einem SQLiteOpenHelper Problem gelöst.


7
2018-06-17 18:11



Sie haben erwähnt, dass Sie eine Klasse erstellt haben, die erweitert wird SQLiteOpenHelper und implementiert die onCreate Methode. Stellen Sie sicher, dass Sie alle Ihre Datenbankauflistungsaufrufe mit dieser Klasse durchführen? Du solltest nur bekommen SQLiteDatabase Objekte über die SQLiteOpenHelper#getWritableDatabase und getReadableDatabase ansonsten der onCreate Methode wird bei Bedarf nicht aufgerufen. Wenn Sie das schon tun, überprüfen Sie, ob th SQLiteOpenHelper#onUpgrade Methode wird stattdessen aufgerufen. Wenn dies der Fall war, wurde die Versionsnummer der Datenbank zu einem bestimmten Zeitpunkt geändert, aber die Tabelle wurde nie richtig erstellt, als dies geschah.

Nebenbei können Sie die Wiederherstellung der Datenbank erzwingen, indem Sie sicherstellen, dass alle Verbindungen zu dieser Datenbank geschlossen und aufgerufen werden Context#deleteDatabaseund dann mit dem SQLiteOpenHelper um Ihnen ein neues db-Objekt zu geben.


2
2018-06-17 05:32



 // @param db, readable database from SQLiteOpenHelper

 public boolean doesTableExist(SQLiteDatabase db, String tableName) {
        Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);

    if (cursor != null) {
        if (cursor.getCount() > 0) {
            cursor.close();
            return true;
        }
        cursor.close();
    }
    return false;
}
  • sqlite verwaltet die Tabelle sqlite_master, die Informationen über alle Tabellen und Indizes in der Datenbank enthält.
  • Hier führen wir einfach den SELECT-Befehl aus, wir erhalten den Cursor mit der Nummer 1, wenn die Tabelle existiert.

1
2017-07-11 14:13



 public boolean isTableExists(String tableName) {
    boolean isExist = false;
    Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);
    if (cursor != null) {
        if (cursor.getCount() > 0) {
            isExist = true;
        }
        cursor.close();
    }
    return isExist;
}

0
2017-09-03 07:22