可以使用 PDO 和 PostgreSQL 返回多个结果集吗?

发布于 2024-07-23 08:37:57 字数 1602 浏览 4 评论 0原文

我想将多个查询分组到 PostgreSQL 中的一个函数中。 将使用 PDO 查询该函数。

函数是:

CREATE OR REPLACE FUNCTION "test_multipe_refcursor"() 
RETURNS SETOF refcursor AS $BODY$

DECLARE
    parentRC refcursor;
    childRC refcursor;

BEGIN

open parentRC FOR
SELECT * FROM parent;
RETURN NEXT parentRC;

open childRC FOR
SELECT * FROM child;
RETURN NEXT childRC;

RETURN;

END;$BODY$
LANGUAGE 'plpgsql' VOLATILE;

ALTER FUNCTION "test_multipe_refcursor"() OWNER TO postgres;

这是 PHP 代码。 “Database”作为一个单例类,设置通常的连接属性,没有什么特别的。

  $database = Database::load();
  $sql = "select * from test_multipe_refcursor();";
  $p = $database->query($sql);

  $i = 1;
  do
  {
     $this->set('set' . $i, $p->fetchAll(PDO::FETCH_ASSOC));
     $i++;
  } while ($p->nextRowset());

  $p->closeCursor();

以及结果。

 PDOException: SQLSTATE[IM001]: Driver does not support this function: driver does not support multiple rowsets in xxxx.php on line 32

这似乎表明它不受支持,但话又说回来,我找不到准确定义什么的列表。

有人设法让这个工作吗?

参考文献:

I would like to group multiple queries into a single function that lives in PostgreSQL. The function will be queried using PDO.

The function is:

CREATE OR REPLACE FUNCTION "test_multipe_refcursor"() 
RETURNS SETOF refcursor AS $BODY$

DECLARE
    parentRC refcursor;
    childRC refcursor;

BEGIN

open parentRC FOR
SELECT * FROM parent;
RETURN NEXT parentRC;

open childRC FOR
SELECT * FROM child;
RETURN NEXT childRC;

RETURN;

END;$BODY$
LANGUAGE 'plpgsql' VOLATILE;

ALTER FUNCTION "test_multipe_refcursor"() OWNER TO postgres;

Here's the PHP code. "Database" as a singleton class that sets up the usual connection properties, nothing special.

  $database = Database::load();
  $sql = "select * from test_multipe_refcursor();";
  $p = $database->query($sql);

  $i = 1;
  do
  {
     $this->set('set' . $i, $p->fetchAll(PDO::FETCH_ASSOC));
     $i++;
  } while ($p->nextRowset());

  $p->closeCursor();

And the result.

 PDOException: SQLSTATE[IM001]: Driver does not support this function: driver does not support multiple rowsets in xxxx.php on line 32

This would seem to indicate that it's not supported, but then again, I cannot find a list defining exactly what is.

Has anyone managed to get this working?

References:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只怪假的太真实 2024-07-30 08:37:57

PostgreSQL 待办事项列表仍然支持返回多个结果集,并且肯定不会达到 8.4。 至于 setof refcursors 方法,您尝试执行的操作不起作用,因为该函数没有返回多个行集 - 它返回一个引用游标行集。 我不确定使用 refcursors 客户端是否有效,但我认为不太可能,即使客户端-服务器协议支持它,PDO 也不太可能有相应的 API。

但是为什么要尝试在一个查询中返回多个结果集呢? 您始终可以单独进行查询。

Support for returning multiple resultsets is still on the PostgreSQL todo list and it will definitely not hit 8.4. As for the setof refcursors method, What you are trying to do doesn't work because the function isn't returning multiple rowsets - it is returning one rowset of refcursors. I'm not sure if using refcursors client side works, but I don't find it likely, even if the client-server protocol supports it, it is unlikely that PDO has an API for that.

But why are you trying to return multiple resultsets in one query? You can always do the queries separately.

晨曦÷微暖 2024-07-30 08:37:57

此 PostgreSQL 文档页面底部附近,有一个描述如何从函数传回一个或多个游标的部分。 基本上,您让调用者指定游标的名称作为参数:

CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $
BEGIN
    OPEN $1 FOR SELECT * FROM table_1;
    RETURN NEXT $1;
    OPEN $2 FOR SELECT * FROM table_2;
    RETURN NEXT $2;
END;
$ LANGUAGE plpgsql;

-- need to be in a transaction to use cursors.
BEGIN;

SELECT * FROM myfunc('a', 'b');

FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;

该页面适用于 PostgreSQL 8.4,但此文档片段至少可以追溯到 8.1(我正在运行的版本)。 正如评论所说,您需要在事务内部才能使用游标,因为它们在每个事务结束时隐式关闭(即,如果自动提交模式打开,则在每个语句末尾)。

Near the bottom of this PostgreSQL doc page, there is a section describing how you can pass back one or more cursors from a function. Basically, you get the caller to specify the name of the cursor(s) as parameters:

CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $
BEGIN
    OPEN $1 FOR SELECT * FROM table_1;
    RETURN NEXT $1;
    OPEN $2 FOR SELECT * FROM table_2;
    RETURN NEXT $2;
END;
$ LANGUAGE plpgsql;

-- need to be in a transaction to use cursors.
BEGIN;

SELECT * FROM myfunc('a', 'b');

FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;

The page is for PostgreSQL 8.4, but this documentation snippet is present at least as far back as 8.1 (the version I'm running). As the comment says, you need to be inside a transaction to use cursors, as they are implicitly closed at the end of each transaction (i.e. at the end of every statement if autocommit mode is on).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文