0

我正在尝试创建一个从用户表返回行的存储过程。我用 pg_ 函数从 php 调用它:pg_prepare($conn, $id, 'SELECT user_read_all()')pg_execute($conn, $id, array()). 可悲的是,我没有仅用于 mysql 的 PDO。

我尝试使用此代码,但有多个问题:

CREATE OR REPLACE FUNCTION user_read_all()
  RETURNS table(user_id INT, user_name VARCHAR, user_email VARCHAR)
AS
  $BODY$
  BEGIN
    return query SELECT
      user_id, user_name, user_email
    FROM
      user;
  END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

通过 pg_fetch,结果是array('test' => string(...))而不是array(user_id => 1, user_name => '', user_email => ''). 我也想切断user_前缀,但是我得到了语法错误:

CREATE OR REPLACE FUNCTION user_read_all()
  RETURNS table(id INT, name VARCHAR, email VARCHAR)
AS
  $BODY$
  BEGIN
    return query SELECT
      user_id as id, user_name as name, user_email as email
    FROM
      user;
  END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

;-(

可以用plpgsql做到这一点吗?

我的目标是做一个只存储过程的接口,但我有严重的疑问......使用mysql这很容易,但是mysql与pgsql相比只有有限的功能......

CREATE PROCEDURE `user_read_all`()
BEGIN
    SELECT `user_id` AS `id`, `user_name` AS `name`, `user_email` AS `email` FROM `user`
    ORDER BY `user_id` DESC;
END;

那么问题是如何修复存储过程和php结果集?

解决方案

CREATE FUNCTION test ()
  RETURNS TABLE (id INT, name VARCHAR, email VARCHAR)
AS
  $BODY$
  BEGIN
    return QUERY SELECT
      "user".user_id, "user".user_name, "user".user_email
    FROM
      "user";
  END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

SELECT * FROM test();

在 php 方面。

4

2 回答 2

1

这是一个返回表格的函数,因此您必须将其视为表格:

SELECT * FROM user_read_all();

在 psql 中尝试两者并仔细查看输出。您的原始方式返回一组行类型,FROM 方式返回列。

关于语法错误 - 你不给它,所以我不能说。

不过,请避免对列/表名使用保留字。诸如“类型”、“名称”、“用户”等之类的东西 - 有关详细信息,请参阅文档。

于 2013-07-03T14:49:00.177 回答
1

这里真正的问题是userPostgreSQL 中的一个保留关键字current_user,与 MySQL 相反,它只是current_user保留的。

您的函数的第一种形式在创建时没有产生语法错误,因为 plpgsql 解析器没有尝试识别列。不过,它在运行时肯定会失败。如果 php 代码没有喊出任何错误,则可能缺少其错误检测代码。

user在 PG 中返回您的登录名,并且可以像使用 table: 一样使用SELECT * FROM user,也可以作为独立表达式使用:SELECT user,[other columns] FROM table...

如果您仍想将其用作表名,则必须将其括在双引号中:(SELECT * FROM "user"假设它是小写的。双引号的另一个效果是它打开了精确的大小写匹配)。

同样对于像您这样只运行查询的函数,您不想使用过程plpgsql语言,而是使用更高效的 sql 语言。在 SQL 中,函数将是:

CREATE OR REPLACE FUNCTION user_read_all()
  RETURNS table(id INT, name VARCHAR, email VARCHAR)
AS
  $BODY$
    SELECT
      user_id as id, user_name as name, user_email as email
    FROM
      "user";
  $BODY$
LANGUAGE sql;

您可以用 来调用它SELECT user_read_all(),但SELECT * from user_read_all()可能是您想要获得 3 个正确的列。

于 2013-07-03T15:11:10.520 回答