У меня есть приложение для Android, которое должно проверить, есть ли в базе данных запись, а если нет, обрабатывать некоторые вещи и, в конечном итоге, вставлять их и просто читать данные из базы данных, если данные действительно существуют. Я использую подкласс SQLiteOpenHelper для создания и получения перезаписываемого экземпляра SQLiteDatabase, который, как я думал, автоматически позаботился о создании таблицы, если он еще не существует (поскольку код для этого в onCreate (... )).
Однако, когда таблица еще не существует, а первый метод запускается на объекте SQLiteDatabase, у меня есть вызов запроса (...), в моем логарифме отображается ошибка "I/Database (26434): sqlite return: код ошибки = 1, msg = no такая таблица: appdata", и, конечно же, таблица appdata не создается.
Любые идеи о том, почему?
Я ищу либо метод для проверки, существует ли таблица (потому что, если это не так, данные, конечно, не в ней, и мне не нужно ее читать, пока я не напишу на нее, что, кажется, правильно создать таблицу) или способ убедиться, что он создан и просто пуст, ко времени первого вызова запроса (...)
ИЗМЕНИТЬ
Это было опубликовано после двух ответов ниже:
Кажется, я нашел проблему. По какой-то причине я решил, что для каждой таблицы должен быть создан другой SQLiteOpenHelper, хотя оба доступа к одному и тому же файлу базы данных. Я думаю, что рефакторинг этого кода использует только один OpenHelper, и создание обеих таблиц внутри него onCreate может работать лучше...
Да, получается, что теория в моем правлении правильная: проблема, вызывающая метод onCreate, не запускаться, заключалась в том, что объекты SQLiteOpenHelper
должны относиться к базам данных и не иметь отдельного для каждой таблицы. Упаковка обеих таблиц в один SQLiteOpenHelper
решила проблему.
Попробуйте следующее:
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;
}
Я ничего не знаю об Android-API для Android, но если вы можете напрямую поговорить с ним в SQL, вы можете сделать это:
create table if not exists mytable (col1 type, col2 type);
который гарантирует, что таблица всегда создается и не вызывает никаких ошибок, если она уже существует.
Хотя на этот вопрос уже есть много хороших ответов, я придумал другое решение, которое, я думаю, более простое. Объедините свой запрос с помощью блока try и следующего 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.
}
}
Это сработало для меня!
Это то, что я сделал:
/* 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;
Вы упомянули, что вы создали класс, который расширяет SQLiteOpenHelper
и реализовал метод onCreate
. Вы уверены, что выполняете всю свою базу данных, приобретаете вызовы с этим классом? Вы должны получать объекты SQLiteDatabase
только через SQLiteOpenHelper#getWritableDatabase
и getReadableDatabase
, иначе метод onCreate
не будет вызываться, когда это необходимо. Если вы делаете это уже проверять и видите, вместо этого вызывается метод SQLiteOpenHelper#onUpgrade
. Если это так, то номер версии базы данных был изменен в какой-то момент времени, но таблица никогда не создавалась должным образом, когда это произошло.
В стороне вы можете принудительно восстановить базу данных, убедившись, что все соединения с ней закрыты и вызывают Context#deleteDatabase
, а затем с помощью SQLiteOpenHelper
, чтобы дать вам новый объект db.
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;
}
// @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;
}
..... Toast t = Toast.makeText(контекст, "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
.....
no such table exists: error
происходит потому, что после создания базы данных с одной таблицей после этого всякий раз, когда вы создаете таблицу в той же базе данных, она дает эту ошибку.
Чтобы решить эту ошибку, вам необходимо создать новую базу данных и внутри метода onCreate() вы можете создать несколько таблиц в одной базе данных.