“function does not exist”,但我真的认为它存在。

15

我是疯了还是太蠢了?

dev=# \df abuse_resolve 
List of functions
-[ RECORD 1 ]-------+------------------------------------------------------------------------------------------------------------------------------------
Schema              | public
Name                | abuse_resolve
Result data type    | record
Argument data types | INOUT __abuse_id bigint, OUT __msg character varying
Type                | normal

dev=# select abuse_resolve('30'::bigint); 
ERROR:  function abuse_resolve(bigint) does not exist
LINE 1: select abuse_resolve('30'::bigint);
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

这是CREATE FUNCTION的代码,我省略了代码的核心部分,但那应该是不相关的:

CREATE OR REPLACE FUNCTION abuse_resolve(INOUT __abuse_id bigint, OUT __msg character varying) RETURNS record AS $_$
DECLARE
    __abuse_status    VARCHAR;
BEGIN
 ...snip...
    UPDATE abuse SET abuse_status    = __abuse_status,
                       edate    = now(),
                       closed_on = now()
                 WHERE abuse_id        = __abuse_id;
    __msg = 'SUCCESS';
END;
$_$ LANGUAGE plpgsql SECURITY DEFINER;

只是为了好玩:

GRANT ALL ON FUNCTION abuse_resolve(INOUT __abuse_id, OUT __msg character varying) TO PUBLIC;
GRANT ALL ON FUNCTION abuse_resolve(INOUT __abuse_id, OUT __msg character varying) TO myuser;

那个函数似乎是存在的。我可能错过了什么?

问题已解决,答案是:我很蠢。我最初定义参数不当,但我的代码使用了正确的参数。有一个多余的bigint不应该出现在那里。


1
你可以发一下 create function 语句吗? - Clodoaldo Neto
你是在同一个会话中执行的吗?使用的是同一个用户吗?搜索路径相同吗? - Erwin Brandstetter
是的,只有一个用户。search_path设置为public,SHOW确认了这一点。我将使用CREATE FUNCTION进行编辑。 - echtish
4个回答

4

嗯,有点奇怪。我做了以下操作:

steve@steve@[local] =# create function abuse_resolve(inout __abuse_id bigint,
                               out __msg text) returns record language plpgsql as
                               $$ begin __msg = 'ok'; end; $$;
CREATE FUNCTION
steve@steve@[local] =# \df abuse_resolve
List of functions
-[ RECORD 1 ]-------+----------------------------------------
Schema              | so9679418
Name                | abuse_resolve
Result data type    | record
Argument data types | INOUT __abuse_id bigint, OUT __msg text
Type                | normal

steve@steve@[local] =# select abuse_resolve('30'::bigint);
-[ RECORD 1 ]-+--------
abuse_resolve | (30,ok)

您是否遇到过与此数据库有关的其他问题?您可以使用dump/restore进行复制,并在新副本上尝试此操作吗?是否使用"public"架构显式限定函数名称有帮助?您正在使用哪个版本的PostgreSQL?

更新:SQL函数对我来说也可以正常工作:

create function abuse_resolve(inout __abuse_id bigint, out __msg text)
  language sql as $$ select $1, 'ok'::text $$;

我能够重现@echtish创建函数的sql代码,而不是使用returns record。然后我看到了您的plpgsql示例,放弃了我的示例并创建了您的示例,它也起作用了。然后我删除了您的示例,现在再次使用最初导致问题的同一函数,但我无法再次重现问题。我在Fedora 16上使用9.1版本。 - Clodoaldo Neto
唯一合理的解释是 search_path 不包括 public 模式。我敢打赌 select public.abuse_resolve('30'::bigint); 可以工作。 - Erwin Brandstetter
@Clodoaldo:我也无法使用SQL函数重现它(9.1,Debian)。 - araqnid
@ErwinBrandstetter:但在这种情况下,我不会期望该函数可以通过\df找到,因为它应用了pg_function_is_visible - araqnid
你说得对,这没有意义。\df 不会显示函数。 - Erwin Brandstetter
版本号为9.1.2。我已尝试使用-c选项进行转储,并以相同的结果重新导入。我定义了类似任务(abuse_deny)的相似函数,它们没有问题。它们使用相同的参数,以相同的方式定义。我认为有些愚蠢的事情我忽略了。 - echtish

4
如果您可以并且那是问题所在,我建议使用。
"set search_path = mainSchemaName, secondOnes" 

为确保函数被正确创建或在直接调用函数的位置指定模式名称。

select schemaName.abuse_resolve('30'::bigint);

就是这样。我忘记在函数之前定义模式名称,这导致它无法工作。谢谢! - Daniel L. VanDenBosch

1

尝试使用这个语法:

SELECT * FROM abuse_resolve('30'::bigint);

谢谢,但是还是不行。仍然出现错误:ERROR: function abuse_resolve(bigint) does not exist - echtish

0

我拥有所有的东西,但模式没有使用。授予模式使用权限解决了这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接