我正在编写一个使用wxSQLite3库的应用程序,该库是用于wxWidgets跨平台GUI编程框架的libsqlite3的包装器。尝试重用预准备语句时,会抛出wxSQLite3Exception。
此示例说明了问题:
#include <wx/string.h>
#include <wx/wxsqlite3.h>
int main() {
wxSQLite3Database::InitializeSQLite();
//create in-memory test database & populate it
wxSQLite3Database db;
db.Open(wxT(":memory:"));
db.ExecuteUpdate(wxT("CREATE TABLE SimpleTable (id INT PRIMARY KEY, val INT);"));
db.ExecuteUpdate(wxT("INSERT INTO SimpleTable VALUES (1, 10);"));
db.ExecuteUpdate(wxT("INSERT INTO SimpleTable VALUES (2, 20);"));
//create a prepared statement we can reuse
wxSQLite3Statement stmt;
stmt = db.PrepareStatement(wxT("SELECT * FROM SimpleTable WHERE id = ?;"));
//first use of statement (works)
stmt.Bind(1, 1);
wxSQLite3ResultSet r_set = stmt.ExecuteQuery();
if (r_set.NextRow()) {
wxPrintf(wxT("id: %i value: %i\n"), r_set.GetInt(wxT("id")), r_set.GetInt(wxT("val")));
}
r_set.Finalize();
//reset and reuse statement
stmt.Reset();
stmt.Bind(1, 2); //**EXCEPTION THROWN HERE**
wxSQLite3ResultSet r_set2 = stmt.ExecuteQuery();
if (r_set2.NextRow()) {
wxPrintf(wxT("id: %i value: %i\n"), r_set2.GetInt(wxT("id")), r_set2.GetInt(wxT("val")));
}
r_set2.Finalize();
//cleanup
stmt.Finalize();
db.Close();
wxSQLite3Database::ShutdownSQLite();
return 0;
}
为简洁起见,删除了异常处理,但来自异常的消息是:
WXSQLITE_ERROR[1000]: Statement not accessible
我使用libsqlite3在普通的C中写了大致相同的代码,它运行没有问题。有谁知道我做错了什么,或者这是否是wxSQLite3中的某种错误?提前感谢您的帮助!
答案 0 :(得分:1)
在SQLite本身,语句和结果集实际上是同一个对象。
wxSQLite3使用引用计数,以便仅在释放最后一个wxSQLite3Statement
或wxSQLite3ResultSet
对象时释放该语句。
这会在相应的析构函数中自动发生。
但是,显式调用Finalize()
会绕过引用计数。
虽然没有必要,但如果要确保在下一个语句执行之前正确释放wxSQLite3ResultSet
资源,只需破坏此对象:
wxSQLite3Statement stmt = ...;
...
{
wxSQLite3ResultSet r_set = stmt.ExecuteQuery();
... r_set.NextRow() ...
// r_set destructed here
}
...
答案 1 :(得分:1)
只要您打算重用准备好的SQL语句,即重置语句并将新值绑定到语句变量,就不能调用方法Finalize - 也不要在准备好的语句上对象本身或从该语句中检索的结果集。
作为方法名称,Finalize,建议,该方法通过调用sqlite3_finalize来完成基础SQLite语句对象(来自SQLite文档的引用:&#34;调用sqlite3_finalize()函数来删除预准备语句。&#34 ;)删除基础SQLite语句对象后,显然无法再访问它。因此你得到例外。
通常,您不需要明确调用方法Finalize。 wxSQLite3负责通过引用计数来完成语句。