2015-08-05 44 views
5

Jestem całkiem nowy dla C++ i wiem trochę o bibliotece pqxx. Chcę zaimplementować instrukcje i powiązać parametry. W PHP jestem przyzwyczajony do robienia tego w taki ładny i zwięzły sposób:Jak przygotować instrukcje i powiązać parametry w PostgreSQL dla C++

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

lub używając znaczników:

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

Próbowałem fugure się z pqxx documentation jak zaimplementować to, ale do moja dokumentacja wygląda jak bałagan i brakuje w nim krótkich i prostych przykładów (jak podałem powyżej). Mam nadzieję, że ktoś może również dostarczyć takie proste przykłady (lub porównywalną prostotę - bez konieczności pisania jakiegoś kodu behemoth), gdy ma do czynienia z Postgresql w.

Odpowiedz

8

Prosty przykład. To po prostu wypisuje liczbę wpisów o wartości identyfikatora 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; 
} 

Funkcja w.prepared() jest nieco zawikłana. Jest podobny do funkcji curry (curry) w haskell, ponieważ przyjmuje parametr i zwraca inną funkcję, która z kolei przyjmuje inny parametr. Tego typu rzeczy.

Dokumentacja mówi:

Jak przekazać te parametry? C++ nie ma dobrego sposobu na przekazanie nieograniczonej, zmiennej liczby argumentów do wywołania funkcji, a kompilator nie wie, ile osób zamierza przejść. Jest na to pewna sztuczka: możesz traktować wartość, którą otrzymujesz z przygotowanej funkcji, którą wywołujesz, by przekazać parametr. To, co otrzymasz z tego połączenia, jest znowu takie samo, więc możesz wywołać je ponownie, aby przekazać kolejny parametr i tak dalej.

Po przeszedł wszystkie parametry w ten sposób można wywołać oświadczenie z parametrami poprzez wywołanie exec na pw

Jeśli istnieje więcej parametrów użyć $ 1 $ 2 itd w funkcji prepare.

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

i dać varibles jak

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

przykładem dynamicznego przygotowania

#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; 
} 

jeśli chcesz obsługiwać inne typy danych używać tej definicji funkcji

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

Że jest bardzo przydatny! Dziękuję Panu! Czy możesz, proszę, trochę o tym wyjaśnić i wyjaśnić, gdzie jest używana metoda 'quote'. Wygląda na to, że widziałem gdzieś tę metodę, ale nie jestem pewien, czy jest ona używana do przygotowania oświadczeń czy wykonywania innej pracy. Jeśli chodzi o tę konstrukcję - 'w.prepared (" przykład ") (dollar1_var) (dollar2_var) .exec()' - jest to rzeczywiście użyteczne, ale nie wiem, czy ktokolwiek może ją zbudować dynamicznie, na podstawie dowolnej liczby parametrów przygotować - coś jak pokazałem w 'PHP' - '$ s-> execute ($ data);' Czy coś takiego można zaimplementować w 'C++'? – Jacobian

+0

@Jacobian Dodałem prosty przykład z dynamicznym przygotowaniem. Nie wiem, co sędziujecie metodą "cytuj". – keutoi

+0

Dziękuję bardzo! Zrobiłeś świetną odpowiedź! – Jacobian