How to prepare statements and bind parameters in Postgresql for C++

前端 未结 2 897
野性不改
野性不改 2020-12-19 08:30

I\'m quite new to C++ and know a little bit about pqxx library. What I want to implement is to prepare statements and bind parameters. In PHP

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-19 09:09

    A simple example. This just prints the number of entries with id value 0.

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

    The function w.prepared() is a bit convoluted. It's similar to a curried(curry) function in haskell, as in it takes a parameter and returns another function which in turn takes another parameter. That kind of thing.

    Documentation says:

    How do you pass those parameters? C++ has no good way to let you pass an unlimited, variable number of arguments to a function call, and the compiler does not know how many you are going to pass. There's a trick for that: you can treat the value you get back from prepared as a function, which you call to pass a parameter. What you get back from that call is the same again, so you can call it again to pass another parameter and so on.

    Once you've passed all parameters in this way, you invoke the statement with the parameters by calling exec on the invocation

    If there are more parameters use $1 $2 and so on in the prepare function.

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

    and give the varibles as

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

    An Example for dynamic preparation

    #include
    #include
    #include
    
    //Just give a vector of data you can change the template to any data type
    pqxx::prepare::invocation& prep_dynamic(std::vector 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 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;
    }
    

    if you want to handle other data types use this function definition

    template pqxx::prepare::invocation& prep_dynamic(std::vector data, pqxx::prepare::invocation& inv)
    {
        for(auto data_val : data)
            inv(data_val);
        return inv;
    }
    

提交回复
热议问题