Noc*_*era 5 c++ database sqlite c++17
我不知道如何在我的 Sqlite3 代码中实现准备好的语句
#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;
}
Run Code Online (Sandbox Code Playgroud)
用户必须输入 newName,并且该变量应用于更新数据库中的字段。这种方式不起作用,因为Sql脚本正在搜索列。在互联网上我发现,我必须使用准备好的声明,但我不知道如何实现它。
jro*_*rok 10
您从一条 sql 语句开始,其中包含您希望稍后绑定的参数的占位符。在这里,我使用一个问号作为占位符,但文档中还描述了其他选项。
std::string sql = "UPDATE company SET name = ? WHERE id = 1";
Run Code Online (Sandbox Code Playgroud)
然后构建一个准备好的语句(或“编译”,正如他们在 sqlite 文档中所说的那样)。您通常会使用sqlite_prepare_v2函数,但还有其他函数(例如,当您的语句以 utf-8 以外的其他方式编码时)。
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)
Run Code Online (Sandbox Code Playgroud)
然后绑定参数。有一大堆可用的功能。您到底使用哪一种取决于您绑定到参数的数据类型。在这里,我们绑定文本,因此我们使用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).
Run Code Online (Sandbox Code Playgroud)
因此,准备好的声明已准备就绪。现在您可以通过将其传递给来执行它sqlite3_step:
sqlite3_step(stmt); // you'll want to check the return value, read on...
Run Code Online (Sandbox Code Playgroud)
现在,当您单步执行一条应该返回结果表行的语句时,SQLITE_ROW只要有结果行要处理,并且SQLITE_DONE没有剩余结果行,该函数就会继续返回。您可以使用sqlite3_column_*系列函数从结果行中获取单列。我会让你自己解决这个问题。
对于您拥有的简单更新语句,将在第一次调用时sqlite3_step返回。SQLITE_DONE更多信息和可能的错误代码请参见此处。
全部完成后,您将通过销毁准备好的语句来完成。
sqlite3_finalize(stmt);
我希望这能让你开始。