Sqlite C ++中的预准备语句如何工作 [英] How does prepared statements in Sqlite C++ work

查看:57
本文介绍了Sqlite C ++中的预准备语句如何工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何在Sqlite3代码中实现准备好的语句

I do not know how to implement prepared statements in my Sqlite3 code

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

static int callback (void* NotUsed, int argc, char** argv, char** azColName) {
    int i;
    for (i = 0; i < argc; i++) {
        std::cout << ("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    std::cout << ("\n");
    return 0;
}

int main (int argc, char* argv[]) {
    sqlite3* db;
    char* zErrMsg = 0;
    int rc;
    char* sql;

    /* Open database */
    rc = sqlite3_open ("test.db", &db);

    if (rc) {
        std::cerr << "Can't open database: \n" << sqlite3_errmsg (db);
        return (0);
    }
    else {
        std::cout << "Opened database successfully\n";
    }
    std::string newName;
    std::cin >> newName;
    /* Create SQL statement */
    sql = "UPDATE company SET name = newName WHERE id = 1";


    /* Execute SQL statement */
    rc = sqlite3_exec (db, sql, callback, 0, &zErrMsg);

    if (rc != SQLITE_OK) {
        std::cout << "SQL error: \n" << zErrMsg;
        sqlite3_free (zErrMsg);
    }
    else {
        std::cout << "Records created successfully\n";
    }
    sqlite3_close (db);
    return 0;
}

用户必须输入newName,并且此变量应用于更新数据库中的字段.这种方式不起作用,因为Sql脚本正在搜索列.在互联网上,我发现必须使用准备好的语句,但是我不知道如何实现它.

The user has to input newName and this variable should be used to Update a field in the Database. This way it does not work, because the Sql script is searching for a column. In the internet I found, that I had to use a prepared statement, but I do not know how to implement it.

推荐答案

您从一个sql语句开始,该语句具有占位符,该占位符表示您以后希望绑定的参数.在这里,我为占位符使用一个问号,但是文档.

You start with an sql statement that has placeholders for the parameters that you wish to bind later. Here, I use a single question mark for the placeholder, but there are other options described in the documentation.

std::string sql = "UPDATE company SET name = ? WHERE id = 1";

然后,您构造一个准备好的语句(或如他们在sqlite文档中所说的那样编译").通常,您将使用 sqlite_prepare_v2 函数,但是有其他(例如,当您的语句使用utf-8以外的其他格式编码时.)

Then you construct a prepared statement (or "compile", as they say it in sqlite documentation). You'll normally use sqlite_prepare_v2 function, but there are others (for when your statement is encoded in something else than utf-8, for example).

sqlite3_stmt* stmt; // will point to prepared stamement object
sqlite3_prepare_v2(
    db,            // the handle to your (opened and ready) database
    sql.c_str(),    // the sql statement, utf-8 encoded
    sql.length(),   // max length of sql statement
    &stmt,          // this is an "out" parameter, the compiled statement goes here
    nullptr);       // pointer to the tail end of sql statement (when there are 
                    // multiple statements inside the string; can be null)

然后绑定参数.有整堆可用的功能.您确切使用哪一个取决于类型您绑定到该参数的数据.在这里,我们绑定文本,因此我们使用 sqlite3_bind_text :

Then you bind the parameter(s). There's a whole bunch of avaliable functions. Which one exactly you use depends on the type of data that you're binding to the parameter. Here, we bind text, so we use sqlite3_bind_text:

std::string newName = /* get name from user */;
sqlite3_bind_text(
    stmt,             // previously compiled prepared statement object
    1,                // parameter index, 1-based
    newName.c_str(),  // the data
    newName.length(), // length of data
    SQLITE_STATIC);   // this parameter is a little tricky - it's a pointer to the callback
                      // function that frees the data after the call to this function.
                      // It can be null if the data doesn't need to be freed, or like in this case,
                      // special value SQLITE_STATIC (the data is managed by the std::string
                      // object and will be freed automatically).

因此,准备好的语句已准备就绪.现在,您将其传递给 sqlite3_step :

So, the prepared statement is ready to go. Now you execute it by passing it to sqlite3_step:

 sqlite3_step(stmt); // you'll want to check the return value, read on...

现在,当您逐步执行本应返回结果表行的语句时,只要有要处理的结果行,此函数将继续返回 SQLITE_ROW SQLITE_DONE ,当没有剩余时.您可以使用 sqlite3_column_ * 函数系列从结果行中获取单个列.我会让你自己解决这个问题.

Now, when you step through a statement that's supposed to return rows of a result table, this function will keep returning SQLITE_ROW as long as there are result rows to process, and SQLITE_DONE when there are none left. You can use sqlite3_column_* family of functions to get the single columns from a result row. I'll let you figure this out on your own.

对于您拥有的简单更新语句, sqlite3_step 将在第一次调用时返回 SQLITE_DONE .此处.

For a simple update statements that you have, sqlite3_step will return SQLITE_DONE on the first call. More info and possible error codes are here.

全部完成后,您将破坏准备好的语句.

When it's all done, you finish by destructing the prepared statement.

sqlite3_finalize(stmt);

我希望这可以帮助您入门.

I hope this should get you started.

这篇关于Sqlite C ++中的预准备语句如何工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆