如何从 C++ 代码调用 PL/pgSQL 函数

Posted

技术标签:

【中文标题】如何从 C++ 代码调用 PL/pgSQL 函数【英文标题】:How Can I Call PL/pgSQL Function From C++ Code 【发布时间】:2012-11-20 13:13:09 【问题描述】:

我正在尝试使用 PL/pgSQL 调用在 PostgreSQL 中声明的函数。为此,我编写了下面的代码。我的功能正在运行,但之后我正在接受“PGRES_FATAL_ERROR”。此外,当我使用“DELETE * FROM TABLE1”之类的 sql 查询更改“select removestopwords()”时,它工作成功。

我正在考虑,即使现在可以正常工作,该错误也可能在将来导致一些大问题。如何调用 PL/pgSQL 函数而不出错?

void removeStopWordsDB(PGconn* conn) 

PGresult *res = PQexec(conn, "select removestopwords()");

if (PQresultStatus(res) != PGRES_COMMAND_OK) 
    printf("removestopwords failed");
    cout<<PQresultStatus(res);
    PQclear(res);
    exit_nicely(conn);


printf("removestopwords - OK\n");

PQclear(res);

【问题讨论】:

我在你的问题中没有看到 plpgsql 函数的定义。 【参考方案1】:

如果您从PQresultStatus 获得PGRES_FATAL_ERROR,您应该使用PQresultErrorField 从结果集中获取所有错误数据以提供有用的错误消息。这将允许您确定此处的实际错误(很可能是从服务器发送的错误)。

考虑创建一个类来保存可以从 q PQresult 指针构造的 PostgreSQL 错误详细信息,例如:

PgError(const PGresult *rs)

  severity = GetErrorField(rs, PG_DIAG_SEVERITY);
  sqlstate = GetErrorField(rs, PG_DIAG_SQLSTATE);
  primary = GetErrorField(rs, PG_DIAG_MESSAGE_PRIMARY);
  // ...

static std::string GetErrorField(const PGresult *rs, int fieldCode)

  const char *message = PQresultErrorField(rs, fieldCode);
  if (message == NULL) return "";
  return std::string(message);

然后您可以,例如,将错误转储到此对象中的流中,以提供详细信息,就像 psql 和朋友所做的那样(尽管严格来说,您还需要输入 SQL 来完成所有这些操作)

【讨论】:

【参考方案2】:

PostgreSQL API 不支持“忽略所有错误”之类的标志。如果您想忽略结果,那么就不要在主机环境中检查结果。但这是一个糟糕的策略。

【讨论】:

以上是关于如何从 C++ 代码调用 PL/pgSQL 函数的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能从 pgAdmin pgScript 调用 PL/pgSQL 函数?

在 PL/pgSQL 中调用另一个函数内部的函数

PL/pgSQL 函数在 pgAdmin 之外无法正确运行

将数组传递给 PostgreSQL PL/pgSQL 函数

从 Ruby on Rails 调用 PL/pgSQL 存储过程

如何在 PL/pgSQL 中创建嵌套函数?