SQLite持久性项目:errorMsg [英] SQLite Persistence project : errorMsg
问题描述
我在NSAssert中使用errorMsg,但我只将其定义为NULL并且从未使用它来获取实际的错误消息。因此,它总是为NULL,并且没有必要在NSAssert中使用它。
< ...>
char * errorMsg = NULL;
sqlite3_stmt * stmt;
if(sqlite3_prepare_v2(database,update,-1,& stmt,nil)
== SQLITE_OK){
sqlite3_bind_int(stmt, 1,i);
sqlite3_bind_text(stmt,2,[field.text UTF8String],-1,NULL);
}
if(sqlite3_step(stmt)!= SQLITE_DONE)
NSAssert(0,@错误更新表:%s,errorMsg );
< ...>
有人会给出解决方案吗?
当我运行应用程序时,没有任何伤害。但是,当我按下主页按钮时,过程暂停并向我显示:
2013-05-20 23:57:50.156 SQLite持久性[5373:c07] *断言失败 - [LPEViewController applicationWillResignActive:],/ Users / Me / Developer / SQLite Persistence / SQLite Persistence / LPEViewController.m:84 2013-05-20 23:57:50.158 SQLite持久性[5373:c07] 由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'更新表错误:(null)'* *首先抛出调用堆栈:(0x2094012 0x11a1e7e 0x2093e78 0xc37665 0x3c09 0xc624f9 0x20ee0c5 0x2048efa 0xb96bb2 0xe2bb1 0xe2c3d 0xece0c 0xf5e74 0xf6beb 0xe8698 0x1fefdf9 0x1fefad0 0x2009bf5 0x2009962 0x203abb6 0x2039f44 0x2039e1b 0x1fee7e3 0x1fee668 0xe5ffc 0x2b4d 0x2a75)的libc ++ abi.dylib:终止称为抛出异常(LLDB)
一些问题:
- <你永远不会设置
errorMsg
。确保将其设置为sqlite3_errmsg
(或直接使用该功能)。 -
您的自定义错误消息(错误更新表)也有点误导,因为这意味着您要报告表的名称,而您选择的变量名表明您确实想报告SQLite错误消息。
-
如果
sqlite3_prepare_v2
失败,则不会报告任何错误消息。此外,如果sqlite3_prepare_v2
失败,您将继续尝试调用sqlite3_step
,而不是停止并报告错误,即使有没有有效的声明要执行。问题在于它无疑会替换在sqlite3_prepare_v2
失败之后收到的有意义的错误消息,其中包含一些关于以错误顺序执行语句的无用消息。 -
您不检查
sqlite3_bind
语句的成功或失败。这样做是明智的(尽管我怀疑你更有可能在sqlite3_prepare_v2
语句中失败)。
无论如何,也许你想要这样的东西:
sqlite3_stmt * stmt;
if(sqlite3_prepare_v2(database,update,-1,& stmt,nil)!= SQLITE_OK)
NSAssert(0,@准备失败:%s,sqlite3_errmsg(数据库) );
if(sqlite3_bind_int(stmt,1,i)!= SQLITE_OK){
sqlite3_finalize(stmt);
NSAssert(0,@bind 1 failure:%s,sqlite3_errmsg(database));
}
if(sqlite3_bind_text(stmt,2,[field.text UTF8String],-1,NULL)!= SQLITE_OK){
sqlite3_finalize(stmt);
NSAssert(0,@bind 2 failure:%s,sqlite3_errmsg(database));
if(sqlite3_step(stmt)!= SQLITE_DONE){
sqlite3_finalize(stmt);
NSAssert(@步骤错误:%s,sqlite3_errmsg(数据库));
}
sqlite3_finalize(stmt);
是否要使用 NSAssert
或只是 NSLog
并立即返回,我将推荐给您,但此代码示例将检查更多SQLite故障情况并报告有意义的错误。
I use errorMsg in my NSAssert, but I only defined it as NULL and never used it to get the actual error message. So, it will always be NULL and there is no point to use it in NSAssert.
<...>
char *errorMsg = NULL;
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, update, -1, &stmt, nil)
== SQLITE_OK) {
sqlite3_bind_int(stmt, 1, i);
sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL);
}
if (sqlite3_step(stmt) != SQLITE_DONE)
NSAssert(0, @"Error updating table: %s", errorMsg);
<...>
will anyone give a solution? when I run the app, there is no harm. but then, when I press the home button, the process paused and shows me this:
2013-05-20 23:57:50.156 SQLite Persistence[5373:c07] * Assertion failure in -[LPEViewController applicationWillResignActive:], /Users/Me/Developer/SQLite Persistence/SQLite Persistence/LPEViewController.m:84 2013-05-20 23:57:50.158 SQLite Persistence[5373:c07] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error updating table: (null)' ** First throw call stack: (0x2094012 0x11a1e7e 0x2093e78 0xc37665 0x3c09 0xc624f9 0x20ee0c5 0x2048efa 0xb96bb2 0xe2bb1 0xe2c3d 0xece0c 0xf5e74 0xf6beb 0xe8698 0x1fefdf9 0x1fefad0 0x2009bf5 0x2009962 0x203abb6 0x2039f44 0x2039e1b 0x1fee7e3 0x1fee668 0xe5ffc 0x2b4d 0x2a75) libc++abi.dylib: terminate called throwing an exception (lldb)
A couple of issues:
You never set the
errorMsg
. Make sure to set it tosqlite3_errmsg
(or just use that function directly).Your custom error message ("Error updating table") is a little misleading, too, as it would imply that you're reporting the name of a table, whereas your choice of variable name suggested you really wanted to report the SQLite error message.
If
sqlite3_prepare_v2
fails, you don't report any error message. Furthermore, rather than stopping and reporting an error ifsqlite3_prepare_v2
failed, you proceed to try to callsqlite3_step
, even though there's no valid statement to perform. The problem with that is that it would undoubtedly replace the meaningful error message you would have received aftersqlite3_prepare_v2
failed with some useless message about executing statements in the wrong order.You don't check the success or failure of your
sqlite3_bind
statements. It would be prudent to do so (though I suspect you're more likely to fail at thesqlite3_prepare_v2
statement).
Anyway, maybe you want something like:
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(database, update, -1, &stmt, nil) != SQLITE_OK)
NSAssert(0, @"prepare failure: %s", sqlite3_errmsg(database));
if (sqlite3_bind_int(stmt, 1, i) != SQLITE_OK) {
sqlite3_finalize(stmt);
NSAssert(0, @"bind 1 failure: %s", sqlite3_errmsg(database));
}
if (sqlite3_bind_text(stmt, 2, [field.text UTF8String], -1, NULL) != SQLITE_OK) {
sqlite3_finalize(stmt);
NSAssert(0, @"bind 2 failure: %s", sqlite3_errmsg(database));
if (sqlite3_step(stmt) != SQLITE_DONE) {
sqlite3_finalize(stmt);
NSAssert(@"step error: %s", sqlite3_errmsg(database));
}
sqlite3_finalize(stmt);
Whether you want to use NSAssert
or just NSLog
and immediately return, I'll defer to you, but this code sample will check more SQLite failure conditions and report meaningful errors.
这篇关于SQLite持久性项目:errorMsg的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!