a) The output string, which should end with std::endl; . The dbHandler argument must be of type. The void function cannot return a value. However, regarding the use of sqlite3 api, the published code is correct.
b) If sqlite3_exec fails, recovery will occur. You only need to free the memory pointed to by retError using sqlite3_free , which you already do.
Below is a minimal example with three bugs fixed by me. It shows that it is correct (the output is "library routine called from sequence" because you cannot call sqlite3_errmsg in the private database descriptor), since it does not generate the error you described. Therefore, if sqlite3_close fails, it is due to an error elsewhere in your program.
The error you are describing can be reproduced by uncommenting the three commented lines. The statement that sqlite3_prepare will then create will not be cleared by calling sqlite3_finalize , and therefore sqlite3_close will result in the error "could not be closed due to unfinalized statements or incomplete backups." Your error is probably caused by something similar.
#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; }
source share