有一个新的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)
哪里错了?
答案 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”,不能用作列名。我把它改成另一个,一切都变好了。