如何调用函数,PostgreSQL

94

我想使用PostgreSQL的函数来保存一些数据。这是创建脚本:

-- Function: "saveUser"(integer, character varying, character varying, character varying, character varying, character varying)

-- DROP FUNCTION "saveUser"(integer, character varying, character varying, character varying, character varying, character varying);

CREATE OR REPLACE FUNCTION "saveUser"("pUserID" integer, "pName" character
varying, "pLastName" character varying, "pUserName" character varying, 
"pPassword" character varying, "peMail" character varying)
RETURNS boolean AS
$BODY$
BEGIN
SELECT 1
FROM "USERS"
WHERE "userID" = $1;

IF FOUND THEN
UPDATE "USERS" 
    SET     "name" = $2,
    "lastName" = $3,
    "userName" = $4,
    "password" = $5,
    "eMail" = $6
WHERE "userID" = $1;
ELSE
    INSERT INTO "USERS"
    ("name", "lastName", "userName", "password", "eMail")
    VALUES
        ($2, $3, $4, $5, $6);
END IF;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION "saveUser"(integer, character varying, character varying, character varying, character varying, character varying) OWNER TO postgres;
PostgreSQL文档指出,如果调用的函数不返回任何结果集,则只需写下函数名称和属性即可。所以我尝试像这样调用函数:
"saveUser"(3, 'asd','asd','asd','asd','asd');

但是我收到了以下错误:

ERROR:  syntax error at or near ""saveUser""
LINE 1: "saveUser"(3, 'asd','asd','asd','asd','asd')
     ^

********** Error **********

ERROR: syntax error at or near ""saveUser""
SQL state: 42601
Character: 1

我有其他返回结果集的函数。我使用 SELECT * FROM "fnc"(...) 调用它们,但出现错误。为什么会这样呢?


编辑:我正在使用 pgAdmin III 查询工具尝试执行 SQL 语句。

6个回答

128

函数调用仍应该是一个有效的SQL语句:

SELECT "saveUser"(3, 'asd','asd','asd','asd','asd');

2
使用这个,我得到了错误信息:“错误:查询没有结果数据的目标”。我想知道这个错误是否与我想要返回一个布尔值有关? - Erkan Haspulat
我尝试了另一个返回void的函数,它可以工作,但如果我想返回一个布尔值呢? - Erkan Haspulat
2
Erkan:尝试结合这两个答案了吗?也就是说,你的调用是错误的,并且你没有为一个预期返回布尔值的函数返回任何内容。此外,为什么你要使用混合大小写标识符,而且还要一直加引号呢? - Alex Brasetvik
@Alex:我声明了一个返回布尔值的函数,并在函数底部插入了 'RETURN 1=1;',然后使用了 'SELECT "saveUser"(..)',但是没有起作用。我还尝试了返回 void,移除 'RETURN 1=1',并使用相同的 SELECT 语句,也没有起作用。 - Erkan Haspulat
2
你看到的新错误信息(“ERROR: query has no destination for result data”)指的是你的函数中的一个错误 - PL/pgSQL中的“SELECT” SQL语句应该始终为“SELECT INTO”。如果你不需要结果,请使用“PERFORM”(http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-NORESULT)。 - Milen A. Radev
“...指的是您的函数中出现了错误。我在函数内部使用了PERFORM而不是SELECT。谢谢Milen。” - Erkan Haspulat

41

对于Postgresql,你可以使用PERFORM。PERFORM仅适用于PL/PgSQL存储过程语言。

DO $$ BEGIN
    PERFORM "saveUser"(3, 'asd','asd','asd','asd','asd');
END $$;

PostgreSQL团队的建议:

提示:如果您想要丢弃SELECT语句的结果,请使用PERFORM。


我想在do begin中使用SELECT而不是PERFOM。如果我使用SELECT,我会遇到一个错误[42601] ERROR:查询没有结果数据的目标,有什么想法吗?我不想使用INTO一些变量,因为我正在使用pgtap函数SELECT has_table('unit_test_output');它应该将输出填充到控制台上。 - San Jaisy

12

在pgadmin中调用PostgreSQL数据库中编写的函数可以有两种方法。

假设我们已经定义了以下函数:

CREATE OR REPLACE FUNCTION helloWorld(name text) RETURNS void AS $helloWorld$
DECLARE
BEGIN
    RAISE LOG 'Hello, %', name;
END;
$helloWorld$ LANGUAGE plpgsql;

我们可以通过以下任一方式调用函数helloworld:
SELECT "helloworld"('myname');

SELECT public.helloworld('myname')

7

如果你的函数不想返回任何内容,你应该声明它为"return void",然后可以像这样调用它:"perform functionName(parameter...);"。


4
当我尝试测试一个非常类似的函数时,遇到了同样的问题。该函数使用SELECT语句来判断是执行插入还是更新操作。这个函数是对一个T-SQL存储过程的重新编写。 当我在查询窗口测试函数时,出现了“查询没有结果数据的目的地”的错误。最终我发现,因为在函数内部使用了SELECT语句,所以在将SELECT的结果赋给本地变量之前,无法在查询窗口中测试该函数。这个问题被解决了。 如果将此主题中的原始函数更改为以下内容,则在从查询窗口调用时可以正常工作:
$BODY$
DECLARE
   v_temp integer;
BEGIN
SELECT 1 INTO v_temp
FROM "USERS"
WHERE "userID" = $1;

-3
你将函数声明为返回布尔值,但它从未返回任何内容。

我在函数定义的底部插入了一行代码“RETURN 1=1”来测试,但没有起到作用。 - Erkan Haspulat
1
真的,但报告的问题并不是由此引起的。 - Andrew Aylett
1
应该是一条注释(不是回答问题) - techkuz

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