Android使用旧模式创建数据库

Android使用旧模式创建数据库,android,sqlite,database-schema,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 stati

有一个新的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;
        }
    }
}
完全重新安装应用程序后,它使用旧模式(不带“章节”表)创建db。在此之后,调用章节的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)
E/SQLiteDatabase﹕ 插入文本时出错=标题=Da测试标题权重=2法则\u id=1顺序=2 \u id=2
android.database.sqlite.SQLiteException:near“order”:编译时语法错误(代码1):插入章节(文本、标题、权重、法律id、顺序、id)值(?,,,,,,,,?)
位于android.database.sqlite.SQLiteConnection.nativePrepareStatement(本机方法)
位于android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
位于android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
位于android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
位于android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:58)
位于android.database.sqlite.SQLiteStatement.(SQLiteStatement.java:31)
位于android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1475)
位于android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1347)
位于kg.zuber.pocketlaware.utils.DBManager.saveLawToDatabase(DBManager.java:106)
位于kg.zuber.pocketlaware.network.DataReceiver$5.onResponse(DataReceiver.java:84)
位于kg.zuber.pocketlaware.network.DataReceiver$5.onResponse(DataReceiver.java:79)
位于com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
位于com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
位于android.os.Handler.handleCallback(Handler.java:730)
位于android.os.Handler.dispatchMessage(Handler.java:92)
位于android.os.Looper.loop(Looper.java:213)
位于android.app.ActivityThread.main(ActivityThread.java:5225)
位于java.lang.reflect.Method.Invokenactive(本机方法)
位于java.lang.reflect.Method.invoke(Method.java:525)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run上(ZygoteInit.java:741)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
在dalvik.system.NativeStart.main(本机方法)

我错在哪里?

问题是在
数据库中有两条SQL语句\u CREATE
语句

如果查看,您会发现这是不受支持的:

不支持用分号分隔的多个语句

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

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);
}

问题是在
数据库\u CREATE
语句中有两条SQL语句

如果查看,您会发现这是不受支持的:

不支持用分号分隔的多个语句

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

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);
}

所以,我发现了问题所在。列\u CHAPTER\u ORDER的值为“ORDER”,不能用作列名。我把它换成了另一个,一切都好了。

所以,我发现了问题所在。列\u CHAPTER\u ORDER的值为“ORDER”,不能用作列名。我刚把它换成另一个,一切都好了。

在列\u LAW\u UPDATE\u DATE之前的最后一个Arment之前还有多余的右括号。在列\u LAW\u UPDATE\u DATE之前的最后一个Arment之前也有多余的右括号