2014-02-18 73 views
0

我的应用程序使用了一些复杂的SQL语句,所以我经常使用execsql可能是坏习惯,即使我可能/应该使用插入或更新等简单操作(下面) 。Android Sqlite SQLiteAbortException不起作用

不过,我想知道这是为什么不工作

String query = "UPDATE OR ABORT " + myTable + " SET " + .... column names and values + WHERE ... 
try { 
    db.execSQL(query); 
} catch (SQLiteAbortException e) { 
    Log.i(TAG, "error in the update"); 

我已经与数据应清楚失败尝试这个(即没有匹配的记录更新),但我不打抓。最初我曾使用UPDATE OR FAIL和SQLiteConstraintException,但是当它没有被捕获时,我尝试了SQLiteAbortException异常

一个异常,指示SQLite程序被中止。这个 可以通过在触发器中调用ABORT或者使用ABORT冲突子句的结果来实现。

我在这里错过了什么?

更新:只需在INSERT/UPDATE或ABORT/FAIL中添加this以供参考如果SQLiteAbortException不是方法,如何捕获更新中止/失败?

+1

我在想,'ABORT'只是一个解决约束违规的情况。如果数据没有更新,那么也没有违规中止。你能否尝试一个违反约束的更新语句(例如用另一个已有的主键值更新主键值)? – tiguchi

+0

@Nobu SQliteAbortException不能按预期方式工作。所以我尝试使用INSERT而不是更新,因为我知道我会因非唯一键而导致违规。没有效果。但是,更改为SQLiteConstraintException确实会抛出错误。在这两种情况下使用UPDATE不会引发错误,但您不希望发生违反约束的错误。 – TrustNoOne

回答

1

我只是试图在Android API级别19的Java源代码部分找到该行为的解释,但SQLiteAbortException(重新)抛出的唯一地方是位于名为DatabaseUtils的静态辅助类中。它最初使用android_database_SQLiteCommon.cpp中的方法从本机代码中抛出。

/*回调例程请求中止*/

我强烈认为一个C回调函数是指具有:当SQLite的返回错误代码4,它被命名为SQLITE_ABORTdocumented as它被抛出。您可以使用SQLite注册回调,并且它们似乎具有某种程度的控制权。所以在我看来,翻译成SQLiteAbortException的错误代码与SQL ABORT子句无关。事实上,我非常怀疑这个异常会被抛出,因为我不认为Android的SQLite数据库驱动程序的本地部分将回调挂钩到SQLite的中止请求。

SQLite documentation of ABORT也是特定种类的错误代码期待它:

ABORT

当适用限制冲突发生时,ABORT分辨率算法中止 与当前的SQL语句SQLITE_CONSTRAINT错误(... snip)

因此,根据SQLite的文档以及原生Android源代码的实际情况,SQLiteConstraintException在这种情况下是可以预料的,显然Android123的文档SQLiteAbortException并不完全正确。

+0

感谢您挖掘所有这些!我将在SQLiteAbortException中放置一个报告并链接此线程。很明显,我的误解(或者期望太高),更新失败也会导致SQLite分支到失败或中止子句。这似乎并不是这种情况,我想唯一可以查看更新是否失败的方法是检查已更改的行数。 – TrustNoOne