PHP调用PostgreSQL函数类型问题?

PHP调用PostgreSQL函数类型问题?,php,sql,database,postgresql,plpgsql,Php,Sql,Database,Postgresql,Plpgsql,我在PostgreSQL/plpgsql中有一个具有以下签名的函数: CREATE OR REPLACE FUNCTION user_login(TEXT, TEXT) RETURNS SETOF _get_session AS $$ ... $$ 其中\u get\u session是一个视图。当从phpPgAdmin调用该函数时,该函数工作正常,但是当我从PHP调用它时,会出现以下错误: 警告:pg_query()[function.pg query]:查询失败:错误:类型 “会话ID”不

我在PostgreSQL/plpgsql中有一个具有以下签名的函数:

CREATE OR REPLACE FUNCTION user_login(TEXT, TEXT) RETURNS SETOF _get_session AS $$ ... $$
其中
\u get\u session
是一个视图。当从phpPgAdmin调用该函数时,该函数工作正常,但是当我从PHP调用它时,会出现以下错误:

警告:pg_query()[function.pg query]:查询失败:错误:类型 “会话ID”不存在上下文:编译PL/pgSQL函数 第69行的/home/sites/blah.com/index.php中第2行附近的“user_login”

函数的DECLARE部分包含以下变量:

oldSessionId session_ids := $1;
newSessionId session_ids := $2;
域会话_id确实存在,并且使用相同域的其他函数在从相同脚本调用时可以工作。PHP如下所示:

$query = "SELECT * FROM $dbschema.user_login('$session_old'::TEXT, '$session'::TEXT)";
$result = pg_query($login, $query);
在调用函数时,我也尝试使用
::session_id
代替
::TEXT
,但是我收到了相同的错误


帮助:o(

只需简化代码即可:

$query = "SELECT * FROM $dbschema.user_login($1, $2)";
$result = pg_query_params($login, $query, array($session_old, $session));
现在您不必再进行SQL注入了


但是,您的函数仍然是错误的,没有数据类型“session_id”。我认为您希望在声明部分使用文本。

如果您的查询包含多行,那么PHP很可能不会将它们作为同一事务的一部分发送。如果是这种情况,您有两个选择

第一个选项是在同一个调用中发送所有查询

pg_query("query1; query2; query3;");
第二种选择(我认为是最好的)是使用事务。这将允许您通过几行进行调用,尽管begin语句很可能需要与初始查询一起发送

pg_query("begin; query1;");
pg_query("query2;");
pg_query("commit;");
如果发生错误,则用回滚替换提交,并且不会对数据库进行任何更改


在使用Postgres时,这实际上是一个很好的经验法则。

我猜pg_query无法解析任意返回类型——它可以处理文本、INT等,但可能不知道如何处理视图。您尝试过“return set of record”吗相反?:|谢谢,我没有,但同样的原则适用于数据库中的所有其他函数。总共有4个函数都返回_whatever_视图集。真的很奇怪。另一个区别是这个函数是由不同的用户运行的(该用户有权运行所涉及的视图)。我无法计算出来:o(谢谢你的提示-我一定会这么做。虽然有一个会话\u ids域-它用于其他函数:o(你100%确定你的脚本和pgAdmin使用相同的数据库吗?公平的问题…是的,所有其他位都工作得很好(在相同的请求/响应上)-只有此函数导致了问题。“会话ID”域是否在可访问的架构中?如果其架构不在“搜索路径”中,可能需要对其进行限定?谢谢Milen。PostgreSQL对我来说是新的(非常-几天),所以很可能是这样。我不习惯限定模式,也不100%确定它在给定会话/连接的作用域中会停留多长时间。我可以说的是,同一脚本中的早期查询是:$result=pg_query($db,“将搜索路径设置为$dbschema;”);那么用户呢?用户需要域和视图的前置任务吗?我找不到任何暗示这是事实……谢谢。我已经解决了这个问题,但这仍然是一些有趣的建议。