由于未完成语句,无法关闭C++ SqLeTe3AxExc

由于未完成语句,无法关闭C++ SqLeTe3AxExc,c++,sql,sqlite,C++,Sql,Sqlite,我在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

我在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);
    }
}
由于这是一个错误,我需要释放错误消息retError并关闭数据库连接。这就是我遇到的问题:

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

unable to close due to unfinalized statements or unfinished backups
我浏览了sqlite3文档,没有找到我没有发布的内容

基于此,我需要帮助:

a修复上述代码

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


谢谢您的帮助。

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

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;
}

自从10年后升级sqlite3以来,我再次访问sqlite3,因此我成功地获得了上述信息。我做了一个sqlite3\u open\u v2,然后做了一个sqlite3\u close,得到了相同的消息。sqlite3\u close\u v2避免该消息


这是一个小错误,但可能对某些人有用。

显示在打开数据库和此函数之间执行的所有其他DB调用。我唯一要做的就是使用相同的sql\u exec结构从日志发出SELECT COUNT*。。。我发现这可能是问题所在……未定稿的语句用定稿,未定稿的备份用定稿完成。可以预期,在以前的sqlite3调用中,您最终会处于这种状态。请提供一个。@qarma:我怀疑任何答案都不会对您的情况有帮助,除非您在出现此错误之前告诉我们正在执行哪些db调用。我认为我不是OP,但我想说的是,在程序中的任何地方,如果不显式调用sqlite3_prepare,可能会命中无法关闭;我的用法完全不同,但这个问题是谷歌搜索到的最接近这个错误代码的问题。这就是赏金。也许可以归结为sqlite在您不期望的情况下为您准备了一些东西?
#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;
}