Подтвердить что ты не робот

Исключение для 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, и я просто пытаюсь ее прочитать


Я не знаю, как, но я, наконец, исправил это. Я только начал снова, на этот раз после этот учебник. Надеюсь, это поможет!

4b9b3361

Ответ 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";