目前我的應用程序只支持SQLite數據庫,但我想同時支持SQLite和MySQL數據庫,所以我正在測試SOCI library以查看它是否符合我的需求。然而,儘管examples and documentation,我不知道法國國際法院如何處理準備好的陳述。如何將一個變量與SOCI庫中的準備好的語句綁定在一起?
當使用SQLite C API,你準備聲明:
sqlite3_stmt* statement;
sqlite3_prepare_v2(database_handle_pointer,
"SELECT * FROM table WHERE user_id=:id;",
-1,
&statement,
NULL);
,以後你綁定一個值: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
}
我該如何與SOCI做到這一點?看起來準備和綁定概念不像本地SQLite API那樣分離。在使用soci :: use()進行準備時,綁定是否必須發生?
更新1:如果我沒有足夠好地解釋這個問題:下面是一個使用SQLite C API的小型工作C++示例。如果我能看到這個使用SOCI的重新實施,它會回答這個問題。
#include <sqlite3.h>
#include <iostream>
// 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 << sqlite3_column_text(statement, 0) << "\n";
}
}
int main()
{
// Create an in-memory database.
sqlite3* database;
if (sqlite3_open(":memory:", &database) != SQLITE_OK)
{
std::cerr << "Error creating database" << std::endl;
return -1;
}
// Create a table and some rows.
sqlite3_exec(database, table, NULL, NULL, NULL);
sqlite3_exec(database, hank, NULL, NULL, NULL);
sqlite3_exec(database, bill, NULL, NULL, NULL);
sqlite3_exec(database, fred, NULL, NULL, NULL);
sqlite3_stmt* statement = make_statement(database);
bind_statement(statement, 2);
execute_statement(statement);
// Cleanup
sqlite3_finalize(statement);
sqlite3_close(database);
return 1;
}
相同的程序使用SOCI部分地實現(注意標記爲HELPME兩個樁函數)
#include <soci/soci.h>
#include <iostream>
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 << table;
database << hank;
database << bill;
database << fred;
soci::statement statement = make_statement(database);
bind_statement(statement, 2);
execute_statement(statement);
}
更新2:我結束了開溝SOCI當我發現cppdb library。與SOCI不同的是,它僅僅是一個非常簡單的封裝器,可以滿足我目前的需求。
謝謝。我在文檔中看到了這一點,但我希望可能有一種替代方法允許use()和into()函數在執行準備語句之前進行綁定,所以變量沒有必須在聲明中「隨身攜帶」。我現在假設這不能在SOCI圖書館中完成。 – 2013-03-24 21:41:49