2013-03-24 36 views
2

目前我的應用程序只支持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不同的是,它僅僅是一個非常簡單的封裝器,可以滿足我目前的需求。

回答

1

文檔介紹瞭如何使用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); 

請注意:user_idname變量的壽命必須至少只要知道的st

+1

謝謝。我在文檔中看到了這一點,但我希望可能有一種替代方法允許use()和into()函數在執行準備語句之前進行綁定,所以變量沒有必須在聲明中「隨身攜帶」。我現在假設這不能在SOCI圖書館中完成。 – 2013-03-24 21:41:49

相關問題