Как использовать мою собственную базу данных sqlite? - PullRequest
7 голосов
/ 05 марта 2010

Я поместил поле моей базы данных в папку "assets". И используйте код из этого блога , чтобы скопировать базу данных в «/ data / data / my_packname / database /», (этот код копирования я запускаю в методе onCreate () при запуске этого приложения), затем используйте select * from ... для получения данных. Но это дает мне исключение: такой таблицы нет.

Кто-то сказал мне, что если я пытаюсь скопировать файл в onCreate () SQLiteOpenHelper, это слишком поздно. Таким образом, код файла копирования не может скопировать весь файл.

Так что мне нужно использовать adb или ddms, чтобы сначала вытащить базу данных?

Итак, кто-нибудь может научить меня, как использовать мою собственную базу данных? Можете ли вы сказать мне настройки?

Ответы [ 7 ]

12 голосов
/ 05 марта 2010

Я использовал инструкции в этом сообщении в блоге и нашел их, находясь на правильном пути, чтобы серьезно усложнить проблему, излишне увеличивая SQLiteOpenHelper.Мне повезло больше:

  1. Создать вспомогательный класс, который создает статическую базу данных, копируя ее в правильный каталог из ресурсов, но не зависаяв следующем формате SQLiteOpenHelper.

  2. Использование того же служебного класса для открытия БД с помощью SQLiteDatabase.openDatabase()

Редактировать: Вотверсия этого служебного класса, которую я создал;это не совсем завершено, но вы получите дрейф.

public class DbUtils {
    private static final String DB_PATH = "/data/data/com.mypackage.myapp/databases/";
    private static final String DB_NAME = "my.db";

    public static void createDatabaseIfNotExists(Context context) throws IOException {
        boolean createDb = false;

        File dbDir = new File(DB_PATH);
        File dbFile = new File(DB_PATH + DB_NAME);
        if (!dbDir.exists()) {
            dbDir.mkdir();
            createDb = true;
        }
        else if (!dbFile.exists()) {
            createDb = true;
        }
        else {
            // Check that we have the latest version of the db
            boolean doUpgrade = false;

            // Insert your own logic here on whether to upgrade the db; I personally
            // just store the db version # in a text file, but you can do whatever
            // you want.  I've tried MD5 hashing the db before, but that takes a while.

            // If we are doing an upgrade, basically we just delete the db then
            // flip the switch to create a new one
            if (doUpgrade) {
                dbFile.delete();
                createDb = true;
            }
        }

        if (createDb) {
            // Open your local db as the input stream
            InputStream myInput = context.getAssets().open(DB_NAME);

            // Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(dbFile);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();
        }
    }

    public static SQLiteDatabase getStaticDb() {
        return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY);
    }
}
1 голос
/ 05 марта 2010

После того, как вы скопировали базу данных, вы должны попробовать закрыть и снова открыть объект SQLiteDatabase перед выполнением любого запроса к нему. У меня была похожая проблема с копированием БД из входного потока, и именно это решило ее для меня.

0 голосов
/ 08 января 2014

Успокойтесь, ребята, после долгих исследований наконец-то обнаружили глупую ошибку за ошибку "нет такой таблицы"

Проверьте имя базы данных в папке Assets, если оно похоже на «DATABASE_NAME.EXTENSION», затем введите полное имя в класс Helper с расширением, которое решило мою проблему.

как, скажем, в разделе «Активы» имя базы данных - это login.sqlite или login.db. положить DB_NAME = login.sqlite полностью с расширением. этот урок теперь отлично работает.

0 голосов
/ 21 июля 2013

Я знаю, что это старый пост, но для тех, кто все еще попадает сюда после поиска в Google или Bing, это решение указанной проблемы:

в createDataBase () есть следующая проверка;

this.getReadableDatabase();

Это проверяет, существует ли база данных с указанным именем, и если нет, создает пустую базу данных, так что ее можно перезаписать с той, которая находится в папке ресурсов. На более новых устройствах это работает безупречно, но есть некоторые устройства, на которых это не работает. В основном старые устройства. Я не знаю точно, почему, но похоже, что функция getReadableDatabase () не только получает базу данных, но и открывает ее. Если вы затем скопируете базу данных из папки ресурсов поверх нее, у нее все еще есть указатель на пустую базу данных, и вы получите таблицу несуществующих ошибок.

Таким образом, чтобы заставить его работать на всех устройствах, вы должны изменить его на следующие строки:

SQLiteDatabase db = this.getReadableDatabase();
if (db.isOpen()){
    db.close();
}

Даже если база данных открыта в чеке, она впоследствии будет закрыта, и это не доставит вам больше хлопот.

0 голосов
/ 01 марта 2013

Я знаю, что это старый вопрос, но я потерял много времени, чтобы выяснить его с помощью всех ответов.


Проблема в том, что устройство хранит базу данных в своей папке data / data /.../ database.Таким образом, когда вы изменяете что-либо о базе данных (имя, добавление таблицы метаданных Android, размер ..), это не будет иметь никакого значения из-за сохраненной базы данных и метода, который проверял существующую базу данных.


Комуполучить самую новую базу данных, после ее изменения вы должны запустить программу, не проверяя существующие базы данных (например, вместо dbExist = checkDataBase(); сделайте ее просто ложной).

dbExist = checkDataBase();

Изменить на:

dbExists = false;

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

Надеюсь, это кому-нибудь поможет,дина

0 голосов
/ 23 декабря 2012

вот моя версия из кода "Сильвио Доннини" :), теперь вы можете легко обновить базу данных.

private static final String DB_PATH = "/data/data/pakagename/databases/";
private static final String DB_NAME = "databaseName";     
private static SQLiteDatabase db;

public static void createDatabaseIfNotExists(Context context,int version) throws IOException {
    boolean createDb = false;

    File dbDir = new File(DB_PATH);
    File dbFile = new File(DB_PATH + DB_NAME);
    if (!dbDir.exists()) {
        dbDir.mkdir();
        createDb = true;
    }
    else if (!dbFile.exists()) {
        createDb = true;
    }
    else {
        // Check that we have the latest version of the db       
         db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY);

        if (db.getVersion() != version) {
            dbFile.delete();
            createDb = true;
        }

    }

    if (createDb) {

        // Open your local db as the input stream
        InputStream myInput = context.getResources().openRawResource(R.raw.database);

        // Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(dbFile);

        // transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
        SQLiteDatabase dbwrite = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE);
        dbwrite.setVersion(version);
        dbwrite.close();
        if (db != null)
            db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY);

    }
}

public static SQLiteDatabase getStaticDb() {
     if (db != null)
         return db;

    return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY);
}
0 голосов
/ 05 марта 2010

Способ создания базы данных из статьи, которую вы опубликовали, немного отличается от того, как это делается в примерах для Android (я не хочу говорить, хорошо это или плохо).

Я научился использовать базы данных из SDK, пример NotePad

Это хороший пример для начала, поскольку он охватывает как тему создания базы данных, так и доступ к базе данных через ContentProvider (это действительно единственный хороший способ получить данные из базы данных, в противном случае у вас будут проблемы при попытке получить данные одновременно из многих мест ваш код).

Вы должны заметить, что SQLiteOpenHelper действительно мощный и «он поможет вам», если вы будете использовать его правильно. Например, он хранит текущую версию базы данных (не версию sqlite, а номер, который вы указали в версии схемы базы данных), и когда вы создаете новую версию приложения с новой структурой базы данных, вы можете обновить текущую схему до новой версии в onUpdate.

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