我第一次使用SQLite,并且我正在尝试学习它的异常处理,因此我在测试应用程序中强制插入错误。发生异常,我看到它写入了Eclipse LogCat输出窗口。但是它不会被代码捕获。我在这里看到了其他关于确保使用正确的异常类型的问题,并认为我已经做对了。知道我错过了什么吗?
在我的主要活动中的以下语句中,myTable
是一个扩展我自己AbstractDbAdapter
的类(其中DatabaseHelper
扩展为SQLiteOpenHelper
)
try {
myTable.create("dupkey");
}
catch (android.database.sqlite.SQLiteConstraintException e) {
Log.e(TAG, "SQLiteConstraintException:" + e.getMessage());
}
catch (android.database.sqlite.SQLiteException e) {
Log.e(TAG, "SQLiteException:" + e.getMessage());
}
catch (Exception e) {
Log.e(TAG, "Exception:" + e.getMessage());
}
样本堆栈跟踪:
Error inserting id="dupkey" last_seen_ts=1360624732 first_seen_ts=1360624732 android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
at android.database.sqlite.SQLiteStatement.native_execute(Native Method)
at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:61)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1582)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1426)
at com.myCompany.testApp.myTable_DbAdapter.create(myTable_DbAdapter.java:51)
myTable
和AbstractDbAdapter
类:
public class myTable_DbAdapter extends AbstractDbAdapter { private static final String DATABASE_TABLE = "myTable"; // column names -- keys for ContentValues() public static final String KEY_ID = "id"; public static final String KEY_FIRST_SEEN = "first_seen_ts"; public static final String KEY_LAST_SEEN = "last_seen_ts"; public myTable_DbAdapter(Context ctx) { super(ctx); } public long create(String id) { long firstSeen = System.currentTimeMillis() / 1000; // SQLite timestamps are in seconds ContentValues args = new ContentValues(); args.put(KEY_ID, id); args.put(KEY_FIRST_SEEN, firstSeen); args.put(KEY_LAST_SEEN, firstSeen); // defaults to firstSeen for a new entry return mDb.insert(DATABASE_TABLE, null, args); } } public abstract class AbstractDbAdapter { protected static final String TAG = "AbstractDbAdapter"; protected DatabaseHelper mDbHelper = null; protected SQLiteDatabase mDb = null; protected static final String TABLE_CREATE_MYTABLE = "create table myTable (" + " id text primary key not null" + ", first_seen_ts integer not null" + ", last_seen_ts integer not null" + ");"; protected static final String DATABASE_NAME = "myDB"; protected static final int DATABASE_VERSION = 1; protected final Context mCtx; protected static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // Note: SQLite requires one execSQL per table db.execSQL(TABLE_CREATE_MYTABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which destroys existing data."); db.execSQL("DROP TABLE IF EXISTS myTable"); onCreate(db); } } public AbstractDbAdapter(Context ctx) { this.mCtx = ctx; } public AbstractDbAdapter open() throws SQLException { mDbHelper = new DatabaseHelper(mCtx); mDb = mDbHelper.getWritableDatabase(); return this; } public void close() { if (mDb != null) { mDb.close(); mDb = null; } if (mDbHelper != null) { mDbHelper.close(); mDbHelper = null; } } }
答案 0 :(得分:24)
我在这里找到答案:SQLiteConstraintException not caught
SQLiteDatabase.insert()方法不会抛出异常。 D'哦!
对于像我这样的其他SQLite新手,如果要在插入数据库时捕获异常,请使用SQLite.insertOrThrow()方法。它将引发一个异常,然后您可以捕获并处理它。
答案 1 :(得分:0)
虽然不是100%与该问题相关,但我使用Room遇到了类似的问题,Google将该问题返回给我进行搜索。就Room而言,似乎没有引发可捕获的异常,insertOrThrow()不存在。在审查https://developer.android.com/reference/kotlin/androidx/room/OnConflictStrategy#ABORT:kotlin.Int时,许多选项都已贬值,但我在这里使用了OnConflictStrategy.IGNORE,因为如果出现问题,它将返回-1。
干杯。