c++ - 如何在 Postgresql for C++ 中准备语句和绑定(bind)参数

标签 c++ postgresql prepared-statement libpqxx

我是 C++ 的新手,对 pqxx 库略知一二。我要实现的是准备语句和绑定(bind)参数。在 PHP 中,我习惯以如此简洁明了的方式执行此操作:

$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 中逃脱如何实现这一点,但对我来说,文档看起来一团糟,并且缺乏简短的示例(如我上面提供的)。我希望有人在处理 C++ 中的 Postgresql 时也能提供这样简单的示例(或相当简单 - 无需编写一些庞大的代码)。

最佳答案

一个简单的例子。这只会打印 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;
}

函数 w.prepared() 有点复杂。它类似于 haskell 中的 curried(curry) 函数,因为它接受一个参数并返回另一个函数,该函数又接受另一个参数。那种事。

文档说:

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

如果有更多参数,请在 prepare 函数中使用 $1 $2 等。

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

并将变量作为

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

关于c++ - 如何在 Postgresql for C++ 中准备语句和绑定(bind)参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31833322/

相关文章:

php - 带有内连接的准备语句,同时在多个数据库上

c++ - 在派生类中使用模板基类模板构造函数

database - 在远程机器上创建 PostgreSQL 数据库

php - 从使用 PHP 到 iPhone 的 MySQL 数据库的分数列表中获取排名

java - 无法写入 JSON : Unable to access lob stream

sql - 按产品类别名称排序行

php - 如何将 IN 子句的一组值传递给 pg_execute() 数组

c++ - 带索引数组的地形(高度图)LOD

c++ - 为什么我不能将这些整数打包在一起?

c++ - 在类声明 block 的内部和外部使用 typedef 语句