簡體   English   中英

c ++ sqlite3_exec由於未定義的語句而無法關閉

[英]c++ sqlite3_exec unable to close due to unfinalised statements

我在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;結尾的輸出行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;
}

自從我重新訪問sqlite3以來,經過10年的升級,我設法獲得了上述消息。 我做了一個sqlite3_open_v2 ,然后是一個sqlite3_close並得到了相同的消息。 sqlite3_close_v2避免了這條消息。

小而愚蠢的錯誤,但也許對某人有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM