Исключение для Android SQLite "нет такой таблицы"
Я начинаю в SQLite и базы данных в Android, и я просто нашел эту проблему. Я прочитал много подобных вопросов, но пока не нашел решения.
Это ошибка, которую я получаю:
E/AndroidRuntime (529): вызвано: android.database.sqlite.SQLiteException: нет такой таблицы: ligas_bd: при компиляции: SELECT * FROM ligas_bd
Это мой код.
DBHelper myDbHelper = new DBHelper(this);
myDbHelper = new DBHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.open();
SQLiteDatabase db = null;
db = myDbHelper.getWritableDatabase();
String[] args = new String[] {""};
Cursor c = db.rawQuery(" SELECT * FROM ligas_bd", args); <---- Error in this line
if (c.moveToFirst()) {
do {
String cod = c.getString(0);
String nombre = c.getString(1);
String flag = c.getString(0);
String cod_url = c.getString(0);
ligas.add(new Item_Liga(nombre, flag, cod, cod_url));
} while(c.moveToNext());
}
}catch(SQLException sqle){
throw sqle;
}
DBHelper.java
public class DBHelper extends SQLiteOpenHelper{
private static String DB_NAME = "ligas_bd";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){ }
else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copiando Base de Datos");
}
}
}
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch(SQLiteException e) { }
if(checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException{
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void open() throws SQLException{
try {
createDataBase();
} catch (IOException e) {
throw new Error("Ha sido imposible crear la Base de Datos");
}
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) { }
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
Я также проверил в своем телефоне данные/данные/data/mypackagename/databases с корневым проводником, и база данных появляется там как обычно.
Моя база данных и основная таблица имеют одинаковое имя, как вы можете видеть на этом рисунке браузера базы данных SQLite:
![screen capture]()
Я не создаю таблицу, я создал ее перед использованием SQLite Database Browser, и я просто пытаюсь ее прочитать
Я не знаю, как, но я, наконец, исправил это. Я только начал снова, на этот раз после этот учебник.
Надеюсь, это поможет!
Ответы
Ответ 1
Это только предположение, но я вижу, что здесь происходят три возможные вещи...
- Вызов
this.getReadableDatabase()
в вашем методе createDatabase()
автоматически создает пустую базу данных.
- Попытка скопировать вашу предварительно созданную базу данных из вашей папки
assets
не выполняется или база данных копируется в неправильное место.
- Пустая база данных, созданная на шаге 1 (выше), является той, которая запрашивается при вызове
db.rawQuery(...)
из вашего основного кода.
Чтобы объяснить далее, полезно использовать источник SQLiteOpenHelper
При создании экземпляра SQLiteOpenHelper
он устанавливает такие вещи, как имя и версия базы данных, но не создает базу данных. Вместо этого первый вызов либо getReadableDatabase()
, либо getWritableDatabase()
проверяет, существует ли база данных и если она ее не создает. После создания пустой базы данных вызывается метод onCreate(...)
, который в вашем случае ничего не делает.
В пункте 2 (выше) - вы говорите, что DB_PATH
- /data/data/mypackagename/databases
. Если это действительно так, и у вас нет trailing /
, тогда строка...
String myPath = DB_PATH + DB_NAME;
... установит myPath
в /data/data/mypackagename/databasesligas_db
. В этом случае, даже если копия из assets
завершается успешно, скопированная база данных не будет там, где вы ожидаете.
Наконец, в пункте 3 (выше), когда вы вызываете db.rawQuery(...)
, экземпляр, который db
указывает на, возвращается предыдущим вызовом getWritableDatabase()
. Предполагая, что копия из assets
не удалась или что она была скопирована на неправильный путь, db
будет указывать на пустую базу данных, созданную на шаге 1.
Ошибка заключается в том, что таблица не существует, и это не ошибка, указывающая на то, что база данных не существует. Единственное логическое объяснение заключается в том, что она выполняет запрос в пустой базе данных, а не тот, который имеет был скопирован из assets
.
EDIT: Еще одна вещь, которую я хотел упомянуть. Не рекомендуется использовать жестко закодированные пути к любой из каталогов Android. Например, хотя на большинстве устройств каталог, в котором создаются базы данных, будет /data/data/<package-name>/databases
, это не гарантия. Это гораздо безопаснее, если вы вызываете метод getDatabasePath(...)
, поскольку он вернет объект File
, который может быть использован для получения пути к каталогу баз данных, используемому классами базы данных Android.
Ответ 2
У меня была такая же проблема, и я исправил ее, очистив проект и удалив приложение с моего тестового устройства и переустановив его. Я считаю, что это произошло, потому что я последовал за другим учебником, который по ошибке создал пустую базу данных. Исправленный код извлекал старую пустую базу данных.
Ответ 3
Если вы используете свое приложение на своем устройстве, перейдите к → Настройки (на устройстве Android) → > application → > найдите приложение → очистите данные и кеш. После этого отлаживаем или устанавливаем снова ваше новое приложение.
Я решил эту проблему, сделав это...
Ответ 4
Исключение очень ясное: вы создали базу данных (ligas_db), но не таблицу внутри нее (нет такой исключение таблицы = нет таблицы с именем ligas_db)
Отметьте это: http://www.vogella.de/articles/AndroidSQLite/article.html
(¿Эрес Антонио Реджио? jaja)
Ответ 5
У вас есть ligas_bd
как имя базы данных, и вы пытаетесь от нее SELECT
.
Ответ 6
Вам нужно создать таблицу сначала, прежде чем выбирать ее. Возможно, вы создали ранее, но вам нужно создать его после открытия соединения с базой данных.
Ответ 7
Моя проблема заключалась в том, что я оставил "/databases/" с конца моего имени пути. Для меня было настолько запутанным, что код работал до того, когда я загружал dbconnection и сохранял его как переменную экземпляра. Затем, когда мне нужно было использовать методы getReadableDatabase() и getWritableDatabase(), они продолжали извлекать пустую базу данных, созданную в "реальном" пути к базам данных.
НЕПРАВИЛЬНО
/Данные/данные/имя_моего_пакета/
ПРАВИЛЬНО
/Данные/данные/имя_моего_пакета/базы данных /
+1 к @Squonk, который, наконец, помог мне проследить это!
Ответ 8
У меня была такая же проблема, попробуйте включить расширение .db в имя файла, например:
private static String DB_NAME = "ligas_bd.db";