我正在开发基于 SQLite[3.6.20] 的 C 库,但遇到了我不明白的行为。当需要关闭数据库连接时,我执行抢先回滚,然后我尝试使用sqlite3_next_stmt()迭代所有未完成的准备好的语句并完成它们:
sqlite3_stmt *stmt;
for (stmt = sqlite3_next_stmt(db, NULL);
stmt;
stmt = sqlite3_next_stmt(db, stmt)) {
sqlite3_finalize(stmt);
}
Run Code Online (Sandbox Code Playgroud)
这确实迭代了几个语句,并且通过一些检测,我可以确认每个语句的sqlite3_finalize()返回SQLITE_OK。
然而,在某些测试用例中,当我此后尝试关闭数据库时,我得到 SQLITE_BUSY(代码 5)并解释说存在未完成的语句。事实上,如果那时我sqlite3_next_stmt()再次调用,它会返回一个我的程序可能已经准备好的语句,但它不在之前由sqlite3_next_stmt().
那么,我认为未完成的声明应该sqlite3_next_stmt()在第一次通过时提供是错误的吗?我是否应该做一些额外的事情来确保我的语句可以通过这种方式清理?
你不应该相信在它完成后stmt包含任何有意义的(甚至是sqlite3_next_stmt())。
反而:
while (stmt = sqlite3_next_stmt(db, NULL))
{
sqlite3_finalize(stmt);
}
Run Code Online (Sandbox Code Playgroud)