Android SQLite исключение "нет такой таблицы" - PullRequest
20 голосов
/ 29 марта 2012

Я начинаю с 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) { }

Я также проверил в своем телефоне данные / данные / mypackagename / database корневого проводника, и база данных там выглядит как обычно.* Моя база данных и главная таблица имеют одно и то же имя, как вы можете видеть на этом рисунке браузера базы данных SQLite:

screen capture

Я не создаю таблицу, я создал ее раньшес помощью браузера баз данных SQLite, и я просто пытаюсь прочитать из него


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

Ответы [ 8 ]

19 голосов
/ 29 марта 2012

Это всего лишь предположение, но я вижу, что здесь происходят три возможные вещи ...

  1. Вызов this.getReadableDatabase() в вашем методе createDatabase() автоматически создает пустую базу данных.
  2. Ваша попытка скопировать предварительно созданную базу данных из папки assets не удалась или база данных копируется в неправильное место.
  3. Пустая база данных, созданная на шаге 1 (выше), запрашивается при вызове db.rawQuery(...) из основного кода.

Для дальнейшего объяснения полезно взглянуть на источник для SQLiteOpenHelper

Когда вы создаете экземпляр SQLiteOpenHelper, он устанавливает такие вещи, как имя и версию базы данных, но не создает базу данных. Вместо этого при первом вызове getReadableDatabase() или getWritableDatabase() проверяется, существует ли база данных, и если она не создает ее. После создания пустой базы данных вызывается метод onCreate(...), который в вашем случае ничего не делает.

Перейдите к пункту 2 (выше) - вы говорите, что DB_PATH - это /data/data/mypackagename/databases. Если это действительно так, и у вас нет трейлинга /, тогда строка ...

String myPath = DB_PATH + DB_NAME;

... установит myPath в /data/data/mypackagename/databasesligas_db. В этом случае, даже если копия из assets завершится успешно, скопированная база данных не будет там, где вы ожидаете.

Наконец, в пункте 3 (выше), когда вы вызываете db.rawQuery(...), экземпляр, на который указывает db, возвращается предыдущим вызовом getWritableDatabase(). Предполагая, что копия из assets не удалась или что она была скопирована по неверному пути, db будет указывать на пустую базу данных, созданную на шаге 1.

Ошибка, которую вы получаете, состоит в том, что таблица не существует, и это не ошибка, указывающая на то, что база данных не существует - единственное логическое объяснение состоит в том, что она выполняет запрос к пустой базе данных, а не к той, которая имеет было скопировано с assets.

РЕДАКТИРОВАТЬ: Еще одна вещь, которую я хотел упомянуть. Не стоит использовать жестко закодированные пути к любому из каталогов Android. Например - хотя на большинстве устройств каталог, в котором создаются базы данных, будет /data/data/<package-name>/databases, это не гарантия. Гораздо безопаснее, если вы вызовете метод getDatabasePath(...), поскольку он вернет объект File, который можно использовать для получения пути к каталогу баз данных, используемому классами баз данных Android.

18 голосов
/ 28 января 2013

У меня была та же проблема, и я исправил ее, очистив проект, удалив приложение с моего устройства тестирования и переустановив его. Я считаю, что это произошло потому, что я последовал другому учебнику, который по ошибке создал пустую базу данных. Исправленный код извлекал старую пустую базу данных.

12 голосов
/ 10 июня 2013

Если вы запускаете приложение на своем устройстве, перейдите к >> Настройки (на устройстве Android) >>> Приложение >>> Найдите ваше приложение >> Очистите данные и кэш.После этого отладьте или установите заново ваше новое приложение ..

Я решил эту проблему, выполнив это ...

1 голос
/ 29 марта 2012

Исключение очень ясно, вы создали базу данных (ligas_db), но не таблицу внутри нее (нет такого исключения таблицы = нет таблицы с именем ligas_db)

Проверьте это: http://www.vogella.de/articles/AndroidSQLite/article.html

(¿Eres Antonio Recio? Jaja)

0 голосов
/ 26 июля 2016

У меня была такая же проблема, попробуйте включить расширение .db в имя файла как:

private static String DB_NAME = "ligas_bd.db";
0 голосов
/ 06 апреля 2013

Моя проблема была в том, что я оставил "/ database /" за пределами моего пути.Что меня так смущало, так это то, что код работал до того, как я загружал соединение db и сохранял его как переменную экземпляра.Затем, когда мне нужно было использовать методы getReadableDatabase () и getWritableDatabase (), они продолжали вытягивать пустую базу данных, созданную по пути «реальных» баз данных.

НЕПРАВИЛЬНО / data / data / mypackagename /

ПРАВИЛЬНО / data / data / mypackagename / database /

+ 1 к @Squonk, чей ответ наконец помог мне отследить это!

0 голосов
/ 30 марта 2012

Вам нужно сначала создать таблицу, прежде чем выбирать из нее. Возможно, вы создали ранее, но вам нужно создать его после открытия подключения к базе данных.

0 голосов
/ 29 марта 2012

У вас есть ligas_bd в качестве имени базы данных, и вы пытаетесь SELECT из нее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...