Currently my application only supports SQLite databases, but I would like to support both SQLite and MySQL databases, so I'm testing out the SOCI library to see if it does what I need. However, despite the examples and documentation, I can't figure out how SOCI handles prepared statements.
When using the SQLite C API, you prepare statement:
使用SQLite C API时,您准备语句:
sqlite3_stmt* statement;
sqlite3_prepare_v2( database_handle_pointer,
"SELECT * FROM table WHERE user_id=:id;",
-1,
&statement,
NULL );
And later you bind a value to the :id place holder, execute the statement and step through the results:
然后将值绑定到:id占位符,执行语句并逐步执行结果:
const sqlite3_int64 user_id = some_function_that_returns_a_user_id();
const int index = sqlite3_bind_parameter_index( statement, ":id" );
sqlite3_bind_int64( statement, index, user_id );
while ( sqlite3_step( statement ) == SQLITE_ROW )
{
// Do something with the row
}
How do I do this with SOCI? It looks like the prepare and bind concepts are not separated like with the native SQLite API. Does the bind have to happen during the prepare using soci::use()?
Update 1: In case I'm not explaining the question well enough: Here's a small, working, C++ example using the SQLite C API. If I could see this re-implemented using SOCI, it would answer the question.
更新1:如果我不能很好地解释这个问题:这是一个使用SQLite C API的小型工作C ++示例。如果我能看到这个使用SOCI重新实现,它将回答这个问题。
#include
#include
// Tables and data
const char* table = "CREATE TABLE test ( user_id INTEGER, name CHAR );";
const char* hank = "INSERT INTO test (user_id,name) VALUES(1,'Hank');";
const char* bill = "INSERT INTO test (user_id,name) VALUES(2,'Bill');";
const char* fred = "INSERT INTO test (user_id,name) VALUES(3,'Fred');";
// Create a SQLite prepared statement to select a user from the test table.
sqlite3_stmt* make_statement( sqlite3* database )
{
sqlite3_stmt* statement;
sqlite3_prepare_v2( database,
"SELECT name FROM test WHERE user_id=:id;",
-1, &statement, NULL );
return statement;
}
// Bind the requested user_id to the prepared statement.
void bind_statement( sqlite3_stmt* statement, const sqlite3_int64 user_id )
{
const int index = sqlite3_bind_parameter_index( statement, ":id" );
sqlite3_bind_int64( statement, index, user_id );
}
// Execute the statement and print the name of the selected user.
void execute_statement( sqlite3_stmt* statement )
{
while ( sqlite3_step( statement ) == SQLITE_ROW )
{
std::cout <
The same program partially implemented using SOCI (Note the two stub functions marked as HELPME)
使用SOCI部分实现相同的程序(注意标记为HELPME的两个存根函数)
#include
#include
const char* table = "CREATE TABLE test ( user_id INTEGER, name CHAR );";
const char* hank = "INSERT INTO test (user_id,name) VALUES(1,'Hank');";
const char* bill = "INSERT INTO test (user_id,name) VALUES(2,'Bill');";
const char* fred = "INSERT INTO test (user_id,name) VALUES(3,'Fred');";
soci::statement make_statement( soci::session& database )
{
soci::statement statement =
database.prepare <<"SELECT name FROM test WHERE user_id=:id";
return statement;
}
void bind_statement( soci::statement& statement, const int user_id )
{
// HELPME: What goes here?
}
void execute_statement( soci::statement& statement )
{
// HELPME: What goes here?
}
int main()
{
soci::session database( "sqlite3", ":memory:" );
database <
Update 2: I ended up ditching SOCI when I found the cppdb library. Unlike SOCI, it is just a very thin wrapper around the native C APIs, which suits my needs at this time.
The documentation explains how to use prepared statements with parameters:
该文档说明了如何使用带参数的预准备语句:
int user_id;
string name;
statement st = (database.prepare <<"SELECT name FROM test WHERE user_id = :id",
use(user_id),
into(name));
user_id = 1;
st.execute(true);
Please note that the lifetime of the user_id and name variables must be at least as long as that of st.
本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ...
[详细]