Создание многотабличной базы данных SQL в Android - PullRequest
4 голосов
/ 23 октября 2010

Я пытаюсь создать многотабличную базу данных для своего приложения для Android. Я следую предложению на этом сайте http://androidforbeginners.blogspot.com/2010/01/creating-multiple-sqlite-database.html сделать это. Я продолжаю получать ошибку ниже. Кажется, ошибка вызвана onCreate таблиц данных.

Если вы посмотрите на мой onCreate в классе DBHelper, у меня есть два комментария. Это позволяет ему работать независимо от того, какой из них остается незарегистрированным.

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

10-23 02:11:35.383: ERROR/AndroidRuntime(300): Caused by: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 0 to 1: /data/data/com.parkingticket/databases/Tickets.db

Заранее спасибо.

Вот мой код

   package com.parkingticket;
   import java.sql.SQLException;
   import android.content.ContentValues;
   import android.content.Context;
   import android.database.Cursor;
   import android.database.sqlite.SQLiteDatabase;
   import android.database.sqlite.SQLiteDatabase.CursorFactory;
   import android.database.sqlite.SQLiteException;
   import android.database.sqlite.SQLiteOpenHelper;
   import android.util.Log;

   public class TicketDBAdapter 
   {
private static final String DATABASE_NAME="Tickets.db";
private static final int DATABASE_VERSION = 1;

private static final String PARKEDCARS_TABLE = "ParkedCars";
private static final String PARKINGMETERS_TABLE = "ParkingMeters";
private static final String PARKINGTICKETS_TABLE = "ParkingTickets";
private static final String POLICEOFFICERS_TABLE = "PoliceOfficers";

// The name and column index for each column in PARKEDCARS
public static final String KEY_CARID = "carID";
    public static final int CARID_COLUMN = 0;
public static final String KEY_CARMAKE = "Make";
    public static final int CARMAKE_COLUMN = 1;
public static final String KEY_CARMODEL = "Model";
    public static final int CARMODEL_COLUMN = 2;
public static final String KEY_CARCOLOR = "Color";
    public static final int CARCOLOR_COLUMN = 3;
public static final String KEY_CARLICENSENUMBER = "LicenseNumber";
    public static final int CARLICENSENUMBER_COLUMN = 4;
public static final String KEY_CARMINUTESPARKED = "MinutesParked";
    public static final int CARMINUTESPARKED_COLUMN = 5;

// The name and column index for each column in PARKINGMETERS
public static final String KEY_METERID = "meterID";
    public static final int METERID_COLUMN = 0;
public static final String KEY_MINUTESPURCHASED = "MinutesPurchased";
    public static final int MINUTESPURCHASED_COLUMN = 1;

// The name and column index for each column in PARKINGTICKETS
    //TODO create the columns and indexs for parking tickets

// The name and column index for each column in POLICEOFFICERS
public static final String KEY_OFFICERID = "officerID";
    public static final int OFFICERID_COLUMN = 0;
public static final String KEY_OFFICERNAME = "Name";
    public static final int OFFICERNAME_COLUMN = 1;
public static final String KEY_OFFICERBADGE = "BadgeNumber";
    public static final int OFFICERBADE_COLUMN = 2;


//Variable to hold the database instance
private SQLiteDatabase ticketDB;

//Context of the application using the database.
private final Context context;

//Database open/upgrade helper
private TicketDBHelper ticketDBHelper;

public TicketDBAdapter(Context _context)
{
    context = _context;
    ticketDBHelper = new TicketDBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
}

public void open() throws SQLiteException
{
    try
    {
        ticketDB = ticketDBHelper.getWritableDatabase();
    }
    catch(SQLiteException ex)
    {
        ticketDB = ticketDBHelper.getReadableDatabase();
    }
}

public void close()
{
    ticketDB.close();
}

 //Insert a new ParkedCar
public long insertParkedCar(ParkedCar _car)
{
    //Create a new row of values to insert
    ContentValues newParkedCarValues = new ContentValues();

    //Assign values for each row
    newParkedCarValues.put(KEY_CARMAKE, _car.getMake());
    newParkedCarValues.put(KEY_CARMODEL, _car.getModel());
    newParkedCarValues.put(KEY_CARCOLOR, _car.getColor());
    newParkedCarValues.put(KEY_CARLICENSENUMBER, _car.getLicenseNumber());
    newParkedCarValues.put(KEY_CARMINUTESPARKED, _car.getMinutesParked());

    //Insert the row
    return ticketDB.insert(PARKEDCARS_TABLE, null, newParkedCarValues);
}

//Remove a ParkedCar based on its index
public boolean removeParkedCar(long _rowIndex)
{
    return ticketDB.delete(PARKEDCARS_TABLE, KEY_CARID + "=" + _rowIndex, null)>0;
}

//Update a ParkedCar's MinutesParked
//TODO Create an update for ParkedCar's minutesParked.

public Cursor getAllParkedCarsCursor()
{
    return ticketDB.query(PARKEDCARS_TABLE, new String[] {KEY_CARID, KEY_CARMAKE, KEY_CARMODEL, KEY_CARCOLOR, KEY_CARLICENSENUMBER, KEY_CARMINUTESPARKED}, null, null, null, null, null);
}

public Cursor setCursorParkedCar(long _rowIndex) throws SQLException
{
    Cursor result = ticketDB.query(true, PARKEDCARS_TABLE, new String []{KEY_CARID}, KEY_CARID + "=" + _rowIndex, null, null, null, null, null);

    if ((result.getCount() == 0) || !result.moveToFirst())
    {
        throw new SQLException("No ParkedCar found for row: " + _rowIndex);
    }

    return result;
}

public static class TicketDBHelper extends SQLiteOpenHelper
{
    public TicketDBHelper(Context context, String name, CursorFactory factory, int version)
    {
        super(context, name, factory, version);
    }

    //SQL Statement to create PARKEDCARS table
    private static final String PARKEDCARS_CREATE = "create table " + PARKEDCARS_TABLE + " (" + KEY_CARID + " integer primary key autoincrement, " + KEY_CARMAKE + " text not null," + KEY_CARMODEL + " text not null," + KEY_CARCOLOR + " text not null," + KEY_CARLICENSENUMBER + " text not null," + KEY_CARMINUTESPARKED + "int not null);";

    //SQL Statement to create ParkingMeters table
    private static final String PARKINGMETERS_CREATE = "create table" + PARKINGMETERS_TABLE + " (" + KEY_METERID + " integer primary key autoincrement, " + KEY_MINUTESPURCHASED + " int not null);";

    //SQL Statement to create ParkingTickets table
    //TODO create the statement for parkingTickets

    //SQL Statement to create PoliceOfficers table
    private static final String POLICEOFFICERS_CREATE = "create table" + POLICEOFFICERS_TABLE + " (" + KEY_OFFICERID + " integer primary key autoincrement, " + KEY_OFFICERNAME + " text not null," + KEY_OFFICERBADGE + "text not null);";

    //Called when no database exists in disk and the helper class needs to create a new one.
    @Override
    public void onCreate(SQLiteDatabase _db)
    {
                //_db.execSQL(PARKEDCARS_CREATE);
          _db.execSQL(PARKINGMETERS_CREATE);
                 //_db.execSQL(POLICEOFFICERS_CREATE);
    }

    //Called when there is a database verion mismatch meaning that the version of the database on disk needs to be upgraded to the current version
    @Override
    public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion)
    {
        //Log the version upgrade.
        Log.w("TaskDBAdapter", "Upgrading from version " + _oldVersion + " to " + _newVersion + ", which will destroy all old data");

        //Upgrade the existing database to conform to the new version
        //Multiple previous versions can be handled by comparing _oldVersoin and _newVersion values

        //The simplest case is to drop teh old table and create a new one.
        _db.execSQL("DROP TABLE IF EXISTS " + PARKEDCARS_TABLE);
        _db.execSQL("DROP TABLE IF EXISTS " + PARKINGMETERS_TABLE);
        _db.execSQL("DROP TABLE IF EXISTS " + POLICEOFFICERS_TABLE);

        onCreate(_db);
    }
}
  }

Ответы [ 4 ]

1 голос
/ 20 апреля 2011

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

Итак, вы объявили столбец без типа.Надеюсь, это помогло.

0 голосов
/ 23 октября 2010

Я написал многостоловое приложение, которое отлично работает.Похоже, у вас могут быть проблемы с открытием существующего файла БД для записи.Я бы предложил удалить это из вашего эмулятора / устройства, увеличить номер версии и перезапустить приложение.Мой открытый метод вставлен здесь.

public DbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

Энтони Нолан

0 голосов
/ 24 октября 2010

Я нашел решение этой проблемы, но не получил прямого ответа на этом сайте.

http://pheide.com/page/11/tab/24#post13

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

0 голосов
/ 23 октября 2010

Поместите оператор Log в ваш метод open(), когда вы поймаете SQLiteException, чтобы проверить, не происходит ли сбой ticketDBHelper.getWritableDatabase(), а затем вызвать ticketDBHelper.getReadableDatabase(), что, как следует из названия, открывает базу данных только для чтения.

...