我在删除我在iOS应用程序中在SQLite中创建的索引时遇到了一些麻烦.我正在使用fmdb.
尝试删除索引时,sqlite3_step始终返回SQLITE_LOCKED.结果,fmdb被捕获在一个无限循环中,它不断尝试重试drop语句(每次都sqlite3_step返回SQLITE_LOCKED),并且语句永远不会成功.
据我所知,在drop语句正常运行之前没有其他进程触及数据库和语句而没有问题.我错过了什么?
这几乎是代码失败的逐字副本:
[db open];
/* ... */
[db executeUpdate:@"DROP INDEX IF EXISTS bookmark_hash_idx;"];
[db close];
Run Code Online (Sandbox Code Playgroud)
db 是指向我的文档目录中的sqlite数据库的指针.
这是来自fmdb的相关代码,如果它有用:
do {
rc = sqlite3_step(pStmt);
retry = NO;
if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) {
// this will happen if the db is locked, like if we are doing an update or insert.
// in that case, retry the step... and maybe wait just 10 milliseconds.
retry = YES;
if (SQLITE_LOCKED == rc) {
rc = sqlite3_reset(pStmt);
if (rc != SQLITE_LOCKED) {
NSLog(@"Unexpected result from sqlite3_reset (%d) eu", rc);
}
}
/* ... */
}
/* ... */
} while (retry);
Run Code Online (Sandbox Code Playgroud)
您可能有打开的结果集阻止DROP INDEX通过.来自SQLite 文档:
"DROP TABLE"例外
当对sqlite3_step()的调用返回SQLITE_LOCKED时,几乎总是适合调用sqlite3_unlock_notify().但是有一个例外.执行"DROP TABLE"或"DROP INDEX"语句时,SQLite会检查是否存在属于同一连接的任何当前正在执行的SELECT语句.如果有,则返回SQLITE_LOCKED.在这种情况下,没有"阻塞连接",因此调用sqlite3_unlock_notify()会导致立即调用unlock-notify回调.如果应用程序然后重新尝试"DROP TABLE"或"DROP INDEX"查询,则结果可能是无限循环.
你应该叫closeOpenResultSets您的FMDatabase对象,以确保所有打开的结果集丢弃索引之前关闭.
| 归档时间: |
|
| 查看次数: |
585 次 |
| 最近记录: |