2015-08-05 13 views
5

Sono abbastanza nuovo per C++ e conosco un po 'la libreria pqxx. Quello che voglio implementare è preparare le istruzioni e collegare i parametri. In PHP Sono abituato a fare questo in modo così bello e conciso:Come preparare istruzioni e parametri di binding in Postgresql per C++

$s = $db->prepare("SELECT id FROM mytable WHERE id = :id"); 
$s->bindParam(':id', $id); 
$s->execute(); 

o utilizzando i token:

$data = array(); 
$data[] = 1; 
$data[] = 2; 
$s = $db->prepare("SELECT id FROM mytable WHERE id = ? or id = ?"); 
$s->execute($data); 

ho cercato di fugure dalla pqxx documentation come implementare questa, ma per la documentazione mi sembra un pasticcio e manca di esempi brevi e semplici (come ho fornito sopra). Spero che qualcuno possa anche fornire esempi così semplici (o di semplicità simile - senza dover scrivere un codice behemoth) quando si ha a che fare con Postgresql in C++.

risposta

8

Un semplice esempio. Questo stampa solo il numero di voci con un valore id 0.

#include<pqxx/pqxx> 
#include<iostream> 

int main() 
{ 
    std::string name = "name"; 
    int id = 0; 
    try { 
     //established connection to data base 
     pqxx::connection c("dbname=mydb user=keutoi"); 
     pqxx::work w(c); 
     //statement template 
     c.prepare("example", "SELECT id FROM mytable WHERE id = $1"); 
     //invocation as in varible binding 
     pqxx::result r = w.prepared("example")(id).exec(); 

     w.commit(); 
     //result handling for accessing arrays and conversions look at docs 
     std::cout << r.size() << std::endl; 
    } 
    catch(const std::exception &e) 
    { 
     std::cerr << e.what() << std::endl; 
     return 1; 
    } 
    return 0; 
} 

La funzione w.prepared() è un po 'contorto. È simile a una funzione al curry (curry) in haskell, poiché accetta un parametro e restituisce un'altra funzione che a sua volta prende un altro parametro. Quel genere di cose.

documentazione dice:

Come si fa a passare questi parametri? C++ non ha un buon modo per passare un numero illimitato e variabile di argomenti a una chiamata di funzione, e il compilatore non sa quanti ne passi. C'è un trucco per questo: puoi trattare il valore che torni da preparato come una funzione, che chiami per passare un parametro. Quello che torni da quella chiamata è lo stesso, quindi puoi chiamarlo di nuovo per passare un altro parametro e così via.

Una volta superato tutti i parametri in questo modo, si richiama la dichiarazione con i parametri chiamando exec sulla invocazione

Se ci sono più parametri usare $ 1 $ 2 e così via nella funzione prepare.

c.prepare("SELECT id name FROM mytable WHERE id = $1 AND name = $2") 

e dare le varibles come

w.prepared("example")(dollar1_var)(dollar2_var).exec() 

un esempio per la preparazione dinamica

#include<pqxx/pqxx> 
#include<iostream> 
#include<vector> 

//Just give a vector of data you can change the template<int> to any data type 
pqxx::prepare::invocation& prep_dynamic(std::vector<int> data, pqxx::prepare::invocation& inv) 
{ 
    for(auto data_val : data) 
     inv(data_val); 
    return inv; 
} 

int main() 
{ 
    std::string name = "name"; 

    //a data array to be used. 
    std::vector<int> ids; 
    ids.push_back(0); 
    ids.push_back(1); 

    try { 
     pqxx::connection c("dbname=mydb user=keutoi"); 
     pqxx::work w(c); 

     c.prepare("example", "SELECT id FROM mytable WHERE id = $1 or id = $2"); 
     pqxx::prepare::invocation w_invocation = w.prepared("example"); 

     //dynamic array preparation 
     prep_dynamic(ids, w_invocation); 
     //executing prepared invocation. 
     pqxx::result r = w_invocation.exec(); 

     w.commit(); 

     std::cout << r.size() << std::endl; 
    } 
    catch(const std::exception &e) 
    { 
     std::cerr << e.what() << std::endl; 
     return 1; 
    } 
    return 0; 
} 

se si desidera gestire altri tipi di dati utilizzano questa definizione di funzione

template<class T> pqxx::prepare::invocation& prep_dynamic(std::vector<T> data, pqxx::prepare::invocation& inv) 
{ 
    for(auto data_val : data) 
     inv(data_val); 
    return inv; 
} 
+0

Quello è molto utile! Grazie Signore! E puoi, per favore, elaborarci un po 'su questo e spiegare dove viene usato il metodo 'quote'. Sembra che abbia visto da qualche parte questo metodo, ma non sono sicuro se sia usato per preparare dichiarazioni o fare un altro lavoro. Per quanto riguarda questo costrutto - 'w.prepared (" example ") (dollar1_var) (dollar2_var) .exec()' - è davvero utile, ma non so se qualcuno possa costruirlo dinamicamente, sulla base di un numero arbitrario di parametri per preparare - qualcosa come ho mostrato in 'PHP' - '$ s-> execute ($ data);' È possibile implementare qualcosa in questo modo in 'C++'? – Jacobian

+0

@Jacobian Ho aggiunto un semplice esempio con la preparazione dinamica. Non so a cosa ti stai arbitrando con il metodo 'quote'. – keutoi

+0

Grazie mille! Hai fatto un'ottima risposta! – Jacobian