Mam aplikację na Androida, która musi sprawdzić, czy istnieje już rekord w bazie danych, a jeśli nie, przetworzyć niektóre rzeczy i ostatecznie je wstawić i po prostu odczytać dane z bazy danych, jeśli dane istnieją. Używam podklasy SQLiteOpenHelper do tworzenia i uzyskiwania instancji SQLiteDatabase z możliwością wielokrotnego zapisu, która według mnie automatycznie zajęła się utworzeniem tabeli, jeśli jeszcze nie istnieje (ponieważ kod do tego znajduje się w onCreate (... ) metoda).
Jednak gdy tabela jeszcze NIE istnieje, a pierwsza metoda uruchomiona na obiekcie SQLiteDatabase, którą mam, to wywołanie zapytania (...), mój logcat pokazuje błąd „I / Database (26434): sqlite zwrócił: błąd code = 1, msg = no such table: appdata "i oczywiście, tabela appdata nie jest tworzona.
Jakieś pomysły, dlaczego?
Szukam jednej z metod, aby sprawdzić, czy tabela istnieje (ponieważ jeśli nie, to danych na pewno nie ma w niej) i nie muszę jej czytać, dopóki do niej nie napiszę, co wydaje się tworzyć tabelę poprawnie) lub sposób, aby upewnić się, że zostanie utworzony i jest po prostu pusty, na czas pierwszego wywołania zapytania (...)
EDYCJA
Zostało to wysłane po dwóch odpowiedziach poniżej:
Myślę, że mogłem znaleźć problem. Z jakiegoś powodu zdecydowałem, że dla każdej tabeli powinien zostać utworzony inny SQLiteOpenHelper, mimo że oba mają dostęp do tego samego pliku bazy danych. Myślę, że refaktoryzacja tego kodu, aby używał tylko jednego OpenHelpera i tworzenie obu tabel w jego onCreate może działać lepiej ...
cursor.close();
select * from sqlite_master where UPPER(name) = 'ROUTES'.
Nie wiem nic o Android SQLite API, ale jeśli potrafisz rozmawiać z nim bezpośrednio w SQL, możesz to zrobić:
create table if not exists mytable (col1 type, col2 type);
Co zapewni, że tabela będzie zawsze tworzona i nie będzie zgłaszać żadnych błędów, jeśli już istniała.
źródło
Chociaż jest już wiele dobrych odpowiedzi na to pytanie, wymyśliłem inne rozwiązanie, które moim zdaniem jest prostsze. Otocz zapytanie blokiem try i następującym haczykiem:
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. } }
U mnie zadziałało!
źródło
e.getMessage().contains("no such table")
jest to gorsze niż używanie wyjątków dla przepływu kontroli. Oba są w złym stylu, ale analizowanie komunikatów o błędach dla określonego tekstu jest nawet w bardzo złym stylu.Oto co zrobiłem:
/* 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;
źródło
Tak, okazuje się, że teoria w mojej edycji była słuszna: problemem, który powodował, że metoda onCreate nie działała, był fakt, że
SQLiteOpenHelper
obiekty powinny odwoływać się do baz danych, a nie mieć osobnej tabeli dla każdej tabeli. Spakowanie obu stołów w jedenSQLiteOpenHelper
rozwiązało problem.źródło
Wspomniałeś, że utworzyłeś klasę, która rozszerza
SQLiteOpenHelper
i zaimplementowałaonCreate
metodę. Czy upewniasz się, że wykonujesz wszystkie wywołania w bazie danych z tą klasą? Państwo powinno być tylko corazSQLiteDatabase
przedmiotów za pośrednictwemSQLiteOpenHelper#getWritableDatabase
agetReadableDatabase
inaczejonCreate
metoda nie zostanie wywołana, gdy jest to konieczne. Jeśli już to robisz, sprawdź i zobacz, czy thSQLiteOpenHelper#onUpgrade
zamiast tego wywoływana jest metoda. Jeśli tak, to numer wersji bazy danych został w pewnym momencie zmieniony, ale tabela nigdy nie została utworzona poprawnie, kiedy to się stało.Nawiasem mówiąc, możesz wymusić odtworzenie bazy danych, upewniając się, że wszystkie połączenia z nią są zamknięte i wywołując,
Context#deleteDatabase
a następnie używając,SQLiteOpenHelper
aby uzyskać nowy obiekt db.źródło
// @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; }
źródło
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; }
źródło
no such table exists: error
nadchodzi, ponieważ po utworzeniu bazy danych z jedną tabelą za każdym razem, gdy tworzysz tabelę w tej samej bazie danych, pojawia się ten błąd.Aby rozwiązać ten błąd, musisz utworzyć nową bazę danych, a wewnątrz metody onCreate () możesz utworzyć wiele tabel w tej samej bazie danych.
źródło
Ważnym warunkiem jest JEŻELI NIE ISTNIEJE aby sprawdzić, czy tabela już istnieje w bazie danych lub jej nie ma
lubić...
String query = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER_PHOTO + "(" + KEY_PLAYER_ID + " TEXT," + KEY_PLAYER_IMAGE + " TEXT)"; db.execSQL(query);
źródło
napotkałem to i poradziłem sobie z tym, próbując złapać tak proste, jak to, robię to, co chcę w tabeli, jeśli nie istnieje, spowoduje błąd, więc złap go przez wyjątki i utwórz :)
SQLiteDatabase db=this.getWritableDatabase(); try{ db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations"); db.execSQL("DELETE FROM vacations"); }catch (SQLiteException e){ db.execSQL("create table o_vacations (id integer primary key ,name text ,vacation text,date text,MONTH text)"); db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations"); db.execSQL("DELETE FROM vacations"); }
źródło
..... Toast t = Toast.makeText (kontekst, "try ...", Toast.LENGTH_SHORT); t.show ();
Cursor callInitCheck = db.rawQuery("select count(*) from call", null); Toast t2a = Toast.makeText(context, "count rows " + callInitCheck.getCount() , Toast.LENGTH_SHORT); t2a.show(); callInitCheck.moveToNext(); if( Integer.parseInt( callInitCheck.getString(0)) == 0) // if no rows then do { // if empty then insert into call
.....
źródło