我正在使用PostgreSQL 9.1.11 我需要将SELECT的结果返回到我的PHP脚本。 php中的调用是这样的:
$res = $pdb->getAssoc("SELECT * FROM my_profile();");
用于说明php中正在发生的事情的类代码
public function getAssoc($in_query) {
$res = pg_query($this->_Link, $in_query);
if($res == FALSE) {
return array("dberror", iconv("utf-8", "windows-1251", pg_last_error($this->_Link)));
}
return pg_fetch_all($res);
}
接下来是我在Postgres的功能。我在更新任何函数时通过删除脚本完全重新创建数据库。 (该项目处于开发的早期阶段。)我几乎没有做过存储过程的经验。
我收到此错误:
structure of query does not match function result type CONTEXT: PL/pgSQL function "my_profile" line 3 at RETURN QUERY )
试着写:
CREATE FUNCTION my_profile()
RETURNS TABLE (_nick text, _email text) AS $$
BEGIN
RETURN QUERY SELECT (nick, email) FROM my_users WHERE id = 1;
END;
$$
LANGUAGE 'plpgsql' SECURITY DEFINER;
表结构是:
CREATE TABLE my_users(
id integer NOT NULL,
nick text,
email text,
pwd_salt varchar(32),
pwd_hash character(128),
CONSTRAINT users_pk PRIMARY KEY (id)
);
当我在表中返回1列时,查询有效。试图在LANGUAGE sql
而不是plpgsql
中重写过程取得了一些成功,但我想坚持使用plpgsql。
Postgres 9.1.11,我使用的php-fpm是完全更新的amd64 Debian wheezy的最新版本。
我想要做的是在关联数组中返回一个包含0到n行的记录集,从proc到php。
答案 0 :(得分:3)
这部分不正确:
RETURN QUERY SELECT (nick, email) FROM my_users WHERE id = 1;
您应该删除nick,email
周围的括号,否则它们会形成一个ROW
类型的唯一列。
这就是它与结果类型不匹配的原因。
答案 1 :(得分:3)
@Daniel已经指出了您的直接问题(错误地使用了括号)。但还有更多:
在此上下文中不要引用语言名称plpgsql
。它是标识符,而不是字符串文字。它现在已被容忍,因为它是一种广泛的反模式。但在将来的版本中可能会将其视为语法错误。
SECURITY DEFINER
子句应附有search_path
的本地设置。请务必阅读according chapter in the manual。
所有东西放在一起,它看起来像这样:
CREATE FUNCTION my_profile()
RETURNS TABLE (nick text, email text) AS
$func$
BEGIN
RETURN QUERY
SELECT m.nick, m.email FROM my_users m WHERE m.id = 1;
END
$func$
LANGUAGE plpgsql SECURITY DEFINER SET search_path = public, pg_temp;
将public
替换为表格的实际架构。
为了避免RETURNS TABLE ...
中的OUT参数与SELECT
语句中的表列之间可能存在命名冲突,我使用给定别名m
表限定列名。