C ++ The correct way to handle sqlite3_prepare and sqlite3_step errors

I have a function that I create using C ++ and Sqlite3, where I will produce a simple SQL statement.

This function expects DML commands without returning (for example: INSERT INTO, UPDATE, or CREATE statements).

I want to know if I can fix possible errors when calling sqlite3. This is the code I'm using:

void execStatement(sqlite* dbHandler, std::string sql)
{
        sqlite3_stmt* compiledStatement;

        int retStatus = sqlite3_prepare(dbHandler, sql.c_str(), -1, &compiledStatement, 0);

        if (retStatus != SQLITE_OK)
        {
            sqlite3_finalize(compiledStatement); // <-- Correct ?

            std::string errorMessage(sqlite3_errmsg(dbHandler));

            throw MyException(retStatus, errorMessage); // MyException accepts 2 params: int and std::string
        }

        retStatus = sqlite3_step(compiledStatement);

        if (retStatus == SQLITE_ERROR || retStatus == SQLITE_BUSY) // <- Correct ?
        {
            sqlite3_finalize(compiledStatement); <-- Correct ?
            std::string errorMessage(sqlite3_errmsg(dbHandler));
            throw MyException(retStatus, errorMessage);
        }

        return;
}

So basically the finalization release will be enough to track events without affecting later calls to the same database?

Thanks for the help.

+4
source share
1 answer

sqlite3_prepare, sqlite3_step sqlite_finalize, , sqlite3_exec ( ): https://www.sqlite.org/c3ref/exec.html?

sqlite_exec :

sqlite3* pDB;
if (sqlite3_open("Database", &pDB) != SQLITE_OK)
{
    // handle it
}

// Execute a command:
char* error = nullptr;
if (sqlite3_exec(pDB, "SELECT * FROM SomeTable WHERE Something='Hi'", _func, &object, &error) != SQLITE_OK)
{
    // Ruh-roh, there was an error:
    cout << error << endl;
    sqlite3_free(error);
}

sqlite3_exec _func object , .

,

create_table (id int, , , )

:

int getCustomers(void* pObject, int columns, char** columnValues, char** columnNames)
{
    if (columns != columns_in_desired_table)
    {
        // we expect this to be called on a specific table. if it not called on a specific
        // table then the result is rubbish
        return 1;
    }

    // ensure we received the right object:
    if (std::vector<std::string>* name = reinterpret_cast<std::vector<std::string>*>(pObject))
        name->push_back(columnValues[1]);

    // indicate success with zero:
    return 0;
}

int main()
{
    sqlite3* db;
    sqlite3_open(&db, "customers.db");
    // this will be assigned from our callback function
    std::vector<std::string> customers;
    char* error = nullptr;
    // getCustomerswill be called on EACH row in Customers 
    sqlite3_exec(db, "select * from Customers where postcode='1234'", &getCustomers, static_cast<void*>(&customers), error);
}

getCustomers - ,

int (*callback)(void*,int,char**,char**)

getCustomers . , SQL:

select * from Customers where postcode='1234'

customers . , , vector . , error , sqlite3_free ( nullptr, sqlite3 ).

+3

All Articles