2015-08-05 8 views
5

Я совершенно новый для C++ и немного знаю о библиотеке pqxx. То, что я хочу реализовать, - это подготовка операторов и привязка параметров. В PHP я привык делать это в такой хороший и лаконично:Как подготовить утверждения и привязать параметры в Postgresql для C++

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

или с использованием токенов:

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

Я пытался фигурное из pqxx documentation, как осуществить это, но мне документация выглядит как беспорядок и не хватает коротких и простых примеров (как я уже говорил выше). Надеюсь, что кто-то может также предоставить такие простые примеры (или сопоставимую простоту - без необходимости писать какой-то бегемот-код) при работе с Postgresql в C++.

ответ

8

Простой пример. Это просто выводит число записей со значением идентификатора 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; 
} 

Функция w.prepared() немного запутанным. Он похож на функцию curried (curry) в haskell, так как в ней принимает параметр и возвращает другую функцию, которая, в свою очередь, принимает другой параметр. Такого рода вещи.

Документация говорит:

Как вы передаете эти параметры? У C++ нет хорошего способа разрешить вам передавать неограниченное число переменных в вызов функции, а компилятор не знает, сколько вы собираетесь пройти. Для этого есть трюк: вы можете обработать возвращаемое вами значение из подготовленной функции, которую вы вызываете для передачи параметра. То, что вы получаете от этого вызова, снова повторяется, поэтому вы можете снова позвонить ему, чтобы передать другой параметр и так далее.

После того, как вы прошли все параметры в этом случае, вы вызываете заявление с параметрами путем вызова Exec на вызове

Если есть другие параметры использовать $ 1 $ 2 и так далее в функции prepare.

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

и дать varibles как

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

пример для динамической подготовки

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

если вы хотите обрабатывать другие типы данных используют это определение функции

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

Это очень полезно! Спасибо, сэр! И можете ли вы, пожалуйста, немного рассказать об этом и объяснить, где используется метод «quote». Кажется, что я видел где-то этот метод, но я не уверен, используется ли он для подготовки заявлений или выполнения какой-либо другой работы. Что касается этой конструкции - 'w.prepared (« example ») (dollar1_var) (dollar2_var) .exec()' - это действительно полезно, но я не знаю, сможет ли кто-нибудь построить это динамически, на основе некоторого произвольного количества параметров для подготовки - что-то вроде того, что я показал в 'PHP' - '$ s-> execute ($ data);' Что-то вроде этого можно реализовать в 'C++'? – Jacobian

+0

@Jacobian Я добавил простой пример с динамической подготовкой. Я не знаю, на что вы ссылаетесь на метод 'quote'. – keutoi

+0

Большое вам спасибо! Вы дали отличный ответ! – Jacobian