C 在sqlite3中,调用步骤失败后是否需要重置?
调用C 在sqlite3中,调用步骤失败后是否需要重置?,c,sqlite,C,Sqlite,调用sqlite3\u step()失败后,是否需要对准备好的语句调用sqlite3\u reset()?我使用的是sqlite3版本3.23.1。我准备的报表的生命周期如下: 在应用程序开始时,我全局执行sqlite3\u prepare\u v2(),并在应用程序的生命周期内保持prepared语句的句柄可用 当我准备好执行查询时,我调用一个sqlite3_bind_*()函数,然后对该语句执行sqlite3_step(),直到返回的不是SQLITE_ROW的内容 然后执行下面的代码来重置语
sqlite3\u step()
失败后,是否需要对准备好的语句调用sqlite3\u reset()
?我使用的是sqlite3版本3.23.1。我准备的报表的生命周期如下:
sqlite3\u prepare\u v2()
,并在应用程序的生命周期内保持prepared语句的句柄可用sqlite3_bind_*()
函数,然后对该语句执行sqlite3_step()
,直到返回的不是SQLITE_ROW
的内容sqlite3\u step()
后发生的代码部分。请注意,变量resultCode
保存上次调用sqlite3\u step()
的返回值
请注意,如果调用步骤失败,我不会执行重置。Google上的文档或搜索结果中没有任何内容表明在出现故障时必须调用sqlite3\u reset()
。事实上,在失败后调用sqlite3\u reset()
也会失败:
如果最近对准备语句S的sqlite3_步骤的调用指示错误,则sqlite3_reset返回适当的错误代码
读了这篇文章,我觉得如果步骤失败,也许我不应该调用重置函数
有人能澄清一下吗?注意在我的例子中,sqlite3\u step()
由于SQLITE\u BUSY
而失败。我正在使用WAL日志模式。一旦准备好的语句的步骤失败,当我调用sqlite3\u step()
时,该准备好的语句将永远处于忙碌状态。调用sqlite3_bind_*()
之后返回sqlite3_bind_int64()失败(21):参数错误或其他API误用
(日志格式是我自己的,但21是错误代码),这使我认为在失败的情况下应该调用reset,因为所有错误似乎都表明数据库正忙,因为准备好的语句由于缺少重置而卡在事务中间
请注意,如果调用步骤失败,我不会执行重置。没有
谷歌上的文档或搜索结果表明
失败时必须调用sqlite3\u reset()
不,不具体,但一定要说
调用sqlite3_reset()函数来重置准备好的语句
对象返回其初始状态,准备重新执行
你加上
事实上,文件
声明在失败后调用sqlite3\u reset()
也将失败:
如果最近对准备语句S的sqlite3_步骤的调用指示错误,则sqlite3_reset返回
正确的错误代码
不,你误解了这一点。“返回适当的错误代码”和“将失败”之间有一个重要的区别。在本摘录的背景下,这一点应该更清楚:
在旧接口中,sqlite3_step()API始终返回
通用错误代码,SQLITE_错误,在除
SQLITE_忙,SQLITE_误用。必须调用sqlite3_reset()或
sqlite3_finalize()以查找特定错误代码之一
这更好地描述了错误
尽管sqlite3_-step()
的行为仅适用于旧接口,而不适用于V2接口,但它解释了为什么sqlite3_-reset()
的返回值会报告以前调用sqlite3_-step()
的结果,而不是报告其自身的成功或失败。这意味着重置本身不能失败,或者至少不能通过其返回代码报告自身的失败
读到这篇文章,我觉得也许我不应该叫重置
如果步骤失败,则返回函数
sqlite3\u step()
的文档在这一点上有这样的表述:
对于3.6.23.1之前(含3.6.23.1)的所有SQLite版本,调用
sqlite3_步骤()返回任何内容后,需要sqlite3_reset()
任何后续调用之前的SQLITE_行除外
sqlite3_步骤()
注意:因此,在sqlite3\u step()
报告错误后调用sqlite3\u reset()
是正确的。医生们接着说
无法使用重置准备好的语句
sqlite3_reset()将导致从
sqlite3_步骤()。但是在版本3.6.23.1(2010-03-26,sqlite3_步骤()之后
在这种情况下,开始自动调用sqlite3_reset()
而不是返回SQLITE_
这似乎与您报告的行为不一致,但请注意
[…]SQLITE\u省略\u自动重置
编译时选项可用于恢复遗留行为
因此,您最安全的选择是无条件地重置语句,而不是避免在报告错误后重置语句。对于许多SQLite3版本来说,这可能是不必要的,但对于某些版本来说,这不是错误或有害的,而且是必要的。谢谢。我认为这些引用中的一些适用于比我更早的版本,但可能有一个错误设计缺陷,在某种程度上这些规则仍然会影响到以后的版本。然而,我认为你的观点是,不管免责声明是否安全,都要慷慨地进行重置。@void.pointer,所有文档引用都是从当前文档中提取的。它们适用于你的版本。interface是这样的,但设计承载着历史包袱并不意味着你可以期望它的行为与文档中的不同。在文档允许不同行为的情况下,是的,我的观点是你的代码应该适应所有文档中的可能性。我知道当前的文档适用于我的版本,但我指的是向后兼容性说明
if (resultCode == SQLITE_DONE || resultCode == SQLITE_ROW)
{
if (sqlite3_reset(m_statement) != SQLITE_OK)
{
LogDbFailure(*m_db, "sqlite3_reset()");
}
}
else
{
LogDbFailure(*m_db, "sqlite3_step()");
success = false;
}