Android使用旧架构创建数据库

时间:2015-08-30 20:21:17

标签: android sqlite database-schema

有一个新的SQLiteOpenHelper:

public class DBManager extends SQLiteOpenHelper {

    public static final int DATABASE_VERSION = 2;

    // Database creation sql statement
    // Indexes should not be used on small tables. © Tutorials Point
    private static final String DATABASE_CREATE =
            "CREATE TABLE " + LAWS_TABLE_NAME + "(" +
            COLUMN_LAW_ID + " INTEGER PRIMARY KEY, " +
            COLUMN_LAW_NAME + " TEXT NOT NULL, " +
            COLUMN_LAW_TEXT + " TEXT NOT NULL, " +
            COLUMN_LAW_COUNTRY + " TEXT NOT NULL, " +
            COLUMN_LAW_VERSION_DATE + " TEXT NOT NULL);" +
            COLUMN_LAW_UPDATE_DATE + " TEXT NOT NULL);" +

            "CREATE TABLE " + CHAPTERS_TABLE_NAME + "(" +
            COLUMN_CHAPTER_ID + " INTEGER PRIMARY KEY, " +
            COLUMN_CHAPTER_TITLE + " TEXT NOT NULL, " +
            COLUMN_CHAPTER_ORDER + " INTEGER NOT NULL, " +
            COLUMN_CHAPTER_WEIGHT + " INTEGER NOT NULL, " +
            COLUMN_CHAPTER_LAW + " INTEGER NOT NULL, " +
            COLUMN_CHAPTER_TEXT + " TEXT);";

    public DBManager(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Method is called during creation of the database
    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(DATABASE_CREATE);
    }

    // Method is called during an upgrade of the database,
    @Override
    public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
        database.execSQL("DROP TABLE IF EXISTS " + LAWS_TABLE_NAME + ";");
        database.execSQL("DROP TABLE IF EXISTS " + CHAPTERS_TABLE_NAME + ";");
        onCreate(database);
    }

    public boolean saveLawToDatabase(Law law) {
        try {
            SQLiteDatabase sdb = this.getWritableDatabase();

            Cursor cursor = sdb.rawQuery("select * from " + LAWS_TABLE_NAME + " where " + COLUMN_LAW_ID + "=" + law.getId(), null);
            if (cursor.moveToFirst()) {
                deleteLaw(law.getId());
            }

            ContentValues newValues = new ContentValues();

            newValues.put(DBManager.COLUMN_LAW_ID, law.getId());
            newValues.put(DBManager.COLUMN_LAW_COUNTRY, law.getCountryCode());
            newValues.put(DBManager.COLUMN_LAW_VERSION_DATE, law.getUpdateDateAsString());
            newValues.put(DBManager.COLUMN_LAW_TEXT, law.getTitle());
            newValues.put(DBManager.COLUMN_LAW_NAME, law.getTitle());

            sdb.insert(DBManager.LAWS_TABLE_NAME, null, newValues);

            for (Chapter chapter:law.getChapters()) {
                newValues = new ContentValues();

                newValues.put(DBManager.COLUMN_CHAPTER_ID , chapter.getId());
                newValues.put(DBManager.COLUMN_CHAPTER_TITLE , chapter.getTitle());
                newValues.put(DBManager.COLUMN_CHAPTER_ORDER , chapter.getOrder());
                newValues.put(DBManager.COLUMN_CHAPTER_WEIGHT , chapter.getWeight());
                newValues.put(DBManager.COLUMN_CHAPTER_LAW , law.getId());
                newValues.put(DBManager.COLUMN_CHAPTER_TEXT, chapter.getText());

                sdb.insert(DBManager.CHAPTERS_TABLE_NAME, null, newValues);
            }


            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

完全重新安装应用程序后,它会创建具有旧架构的数据库(没有"章节"表)。之后,为章节调用sdb.insert会给我跟踪追溯:

E/SQLiteDatabase﹕ Error inserting text= title=Da test title weight=2 law_id=1 order=2 _id=2
    android.database.sqlite.SQLiteException: near "order": syntax error (code 1): , while compiling: INSERT INTO chapters(text,title,weight,law_id,order,_id) VALUES (?,?,?,?,?,?)
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
            at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
            at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1475)
            at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1347)
            at kg.zuber.pocketlawyer.utils.DBManager.saveLawToDatabase(DBManager.java:106)
            at kg.zuber.pocketlawyer.network.DataReceiver$5.onResponse(DataReceiver.java:84)
            at kg.zuber.pocketlawyer.network.DataReceiver$5.onResponse(DataReceiver.java:79)
            at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
            at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:213)
            at android.app.ActivityThread.main(ActivityThread.java:5225)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
            at dalvik.system.NativeStart.main(Native Method)

哪里错了?

2 个答案:

答案 0 :(得分:0)

问题是你的DATABASE_CREATE语句中有两个SQL语句。

如果你看the documentation for execSQL(),就会发现这不受支持:

  

不支持以分号分隔的多个语句。

只需将每个表创建语句分开:

private static final String DATABASE_CREATE_LAWS =
        "CREATE TABLE " + LAWS_TABLE_NAME + "(" +
                COLUMN_LAW_ID + " INTEGER PRIMARY KEY, " +
                COLUMN_LAW_NAME + " TEXT NOT NULL, " +
                COLUMN_LAW_TEXT + " TEXT NOT NULL, " +
                COLUMN_LAW_COUNTRY + " TEXT NOT NULL, " +
                COLUMN_LAW_VERSION_DATE + " TEXT NOT NULL);" +
                COLUMN_LAW_UPDATE_DATE + " TEXT NOT NULL);";

private static final String DATABASE_CREATE_CHAPTERS =
        "CREATE TABLE " + CHAPTERS_TABLE_NAME + "(" +
                COLUMN_CHAPTER_ID + " INTEGER PRIMARY KEY, " +
                COLUMN_CHAPTER_TITLE + " TEXT NOT NULL, " +
                COLUMN_CHAPTER_ORDER + " INTEGER NOT NULL, " +
                COLUMN_CHAPTER_WEIGHT + " INTEGER NOT NULL, " +
                COLUMN_CHAPTER_LAW + " INTEGER NOT NULL, " +
                COLUMN_CHAPTER_TEXT + " TEXT);";

然后在onCreate()方法中执行两个语句:

@Override
public void onCreate(SQLiteDatabase database) {
    database.execSQL(DATABASE_CREATE_LAWS);
    database.execSQL(DATABASE_CREATE_CHAPTERS);
}

答案 1 :(得分:0)

所以,我发现了问题。 COLUMN_CHAPTER_ORDER的值是“order”,不能用作列名。我把它改成另一个,一切都变好了。