gpt4 book ai didi

由于未完成的语句,c++ sqlite3_exec 无法关闭

转载 作者:IT王子 更新时间:2023-10-29 06:29:25 25 4
gpt4 key购买 nike

我在 Ubuntu (c++) 上有以下使用 Sqlite3 的代码:

void test_function(dbHandler)
{
char *retError = 0;

std::string sql("INSERT INTO LOG (LAST_CHANGED_DATE_TIME) VALUES ('TEST');");

int returnStatus = sqlite3_exec(dbHandler, sql.c_str(), 0, 0, &retError);

std::cout << "RetStatus = " << returnStatus << "; " << retError << s

if (returnStatus == SQLITE_OK)
return sqlite3_changes(dbHandler);
else
{
sqlite3_free(retError);
sqlite3_close(dbHandler);
}
}

sqlite3_exec 语句sql 被错误地测试它的失败行为(在那种情况下字段名不匹配)。我从 sqlite3_exec 得到正确的状态为:

 Status = 1; table Log has no column named last_changed_date_time

因为这是一个错误,我需要释放错误消息(retError)并关闭数据库连接。这是我遇到问题的地方:

调用 sqlite3_close 时,我收到以下异常消息:

unable to close due to unfinalized statements or unfinished backups

我浏览了 sqlite3 文档,但找不到我没有在这里发布的内容...

基于此,我需要帮助:

a) 修复上面的代码。

b) 了解在发生错误时从 sqlite3_exec 恢复的正确方法。

感谢您的帮助。

最佳答案

a) 应以 std::endl; 结尾的输出行。 dbHandler 参数必须有一个类型。 void 函数不能不返回值。但是,关于使用 sqlite3 api,发布的代码是正确的。

b) 如果出现错误,sqlite3_exec 将进行恢复。您只需使用 sqlite3_free 释放 retError 指向的内存,您已经在这样做了。

下面是一个最小的运行示例,其中修复了我描述的 3 个错误。它表明它是正确的(“库例程乱序调用”输出是因为您不能在关闭的数据库句柄上调用 sqlite3_errmsg),因为它不会产生您描述的错误。因此,如果 sqlite3_close 失败,那是因为程序中其他地方的错误。

您描述的错误可以通过取消注释 3 个注释行来重现。然后将由 sqlite3_prepare 创建的语句不会通过调用 sqlite3_finalize 进行清理,因此 sqlite3_close 将导致“由于无法关闭到未完成的语句或未完成的备份”错误。您的错误可能是由类似的原因引起的。

#include <iostream>
#include <sqlite3.h>

void test_function(sqlite3 * dbHandler)
{
char *retError = 0;

std::string sql("INSERT INTO LOG (LAST_CHANGED_DATE_TIME) VALUES ('TEST');");

int returnStatus = sqlite3_exec(dbHandler, sql.c_str(), 0, 0, &retError);

std::cout << "RetStatus = " << returnStatus << "; " << retError << std::endl;

if (returnStatus == SQLITE_OK)
return; // sqlite3_changes(dbHandler);
else
{
sqlite3_free(retError);
sqlite3_close(dbHandler);
}
}

int main()
{
sqlite3 * dbHandler;
sqlite3_open("test.sqlite", &dbHandler);
sqlite3_exec(dbHandler, "CREATE TABLE LOG (DUMMY);", 0, 0, 0);

// sqlite3_stmt * test;
// const char * sql = "INSERT INTO LOG (DUMMY) VALUES ('TEST');";
// sqlite3_prepare(dbHandler, sql, -1, &test, 0);

test_function(dbHandler);

std::cout << "Last error: " << sqlite3_errmsg(dbHandler) << std::endl;
return 0;
}

关于由于未完成的语句,c++ sqlite3_exec 无法关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29957870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com