begin
db = SQLite3::Database.open "dbfile.db"
dbins = db.prepare("INSERT INTO table(a,b,c) VALUES (?,?,?);")
dbins.execute(vala,valb,valc)
rescue SQLite3::Exception => e
puts("Something went wrong: " + e)
ensure
db.close if db
end
这就是我用来打开SQLite3数据库并将数据写入其中的代码。
我的问题是这段代码总是给我以下错误:
unable to close due to unfinalized statements or unfinished backups
如果我删除了db.close if db
部分,那么它可以工作,但是在脚本运行了几个小时之后,我收到了too many open files
错误。请不要建议我提高我的inode文件限制,这只是解决更大问题的临时解决方案。
我不希望脚本仅使数据库永远保持打开状态,每当发生事件时,我都希望它打开数据库,写入数据并再次关闭它,以达到预期的工作效果。
请注意,由于评论中的原因,this答案无济于事。
我必须做什么才能“完成”语句,以便可以关闭数据库?我试图在关闭数据库之前只添加一个sleep(5)
,但这没有任何效果。
我发现this问建议在语句中使用finalize,但这似乎只与C / C ++接口有关,与ruby的sqlite3没有关系。
答案 0 :(得分:1)
阅读红宝石宝石的源代码很有帮助。具体来说,文件statement.c的以下代码块:
/* call-seq: stmt.close
*
* Closes the statement by finalizing the underlying statement
* handle. The statement must not be used after being closed.
*/
static VALUE sqlite3_rb_close(VALUE self)
{
sqlite3StmtRubyPtr ctx;
Data_Get_Struct(self, sqlite3StmtRuby, ctx);
REQUIRE_OPEN_STMT(ctx);
sqlite3_finalize(ctx->st);
ctx->st = NULL;
return self;
}
因此,在语句上使用.close
(例如,代码中dbins.close
之后的.execute
)将最终确定语句并使我能够关闭数据库文件。