【问题标题】:How to call a function, PostgreSQL如何调用函数,PostgreSQL
【发布时间】:2010-12-29 12:39:30
【问题描述】:

我正在尝试使用 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;

PostreSQL 文档指出,要调用一个不返回任何结果集的函数,只写它的名称和属性就足够了。所以我尝试这样调用函数:

"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 语句。

【问题讨论】:

    标签: postgresql function-call


    【解决方案1】:

    我们可以有两种方式调用 pgadmin 中为 postgre sql 数据库编写的函数。

    假设我们定义了如下函数:

    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')
    

    【讨论】:

      【解决方案2】:

      对于 Postgresql,您可以使用 PERFORM。 PERFORM 仅在 PL/PgSQL 过程语言中有效。

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

      postgres 团队的建议:

      提示:如果要丢弃 SELECT 的结果,请改用 PERFORM。

      【讨论】:

      • 我想在里面使用 SELECT 而不是 PERFOM 开始。如果我使用 SELECT 我将面临一个错误,因为 [42601] ERROR: query has no destination for result data 不知道为什么,我不想使用 INTO 某个变量,因为我正在使用 pgtap 函数 SELECT has_table('unit_test_output');它应该填充控制台上的输出
      【解决方案3】:

      我在尝试测试一个非常相似的函数时遇到了同样的问题,该函数使用 SELECT 语句来决定是否应该执行 INSERT 或 UPDATE。此函数是对 T-SQL 存储过程的重写。
      当我从查询窗口测试函数时,我收到错误“查询没有结果数据的目的地”。我终于发现,因为我在函数中使用了 SELECT 语句,所以我无法从查询窗口测试函数,直到我使用 INTO 语句将 SELECT 的结果分配给局部变量。这解决了问题。

      如果此线程中的原始函数更改为以下函数,则在从查询窗口调用时它将起作用,

      $BODY$
      DECLARE
         v_temp integer;
      BEGIN
      SELECT 1 INTO v_temp
      FROM "USERS"
      WHERE "userID" = $1;
      

      【讨论】:

        【解决方案4】:

        如果你的函数不想返回任何东西,你应该将它声明为“return void”,然后你可以像这样调用它“perform functionName(parameter...);”

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

          • 使用这个,我得到了错误; “错误:查询没有结果数据的目的地”。我想知道这个错误是否与我想要返回布尔值有关?
          • 我用另一个返回 void 的函数尝试了这个,它可以工作,但是如果我想返回一个布尔值怎么办?
          • Erkan:尝试结合这两个答案? IE。您的调用是错误的,并且您没有为预期返回 bool 的函数返回任何内容。此外,为什么你必须一直引用混合大小写的标识符?
          • @Alex:我声明函数返回布尔值,并插入'RETURN 1=1;'在函数的底部,然后使用 'SELECT "saveUser"(..)' 但它不起作用。我还尝试返回 void,删除 'RETURN 1=1',并使用上面相同的 SELECT 语句,也没有用。
          • 您看到的新错误消息(“错误:查询没有结果数据的目的地”)指的是您的函数中的错误 - PL/pgSQL 中的“SELECT”SQL 语句应始终为“SELECT”进入”。如果您不需要结果,请使用“PERFORM”(postgresql.org/docs/current/static/…)。
          【解决方案6】:

          您将函数声明为返回布尔值,但它从不返回任何内容。

          【讨论】:

          • 我在函数定义的底部插入了“RETURN 1=1”这一行,只是为了测试这一点,没有用。
          • 是的,但报告的问题不是由此引起的。
          • 应该是评论(不回答问题)
          猜你喜欢
          • 1970-01-01
          • 2012-09-30
          • 1970-01-01
          • 2016-11-10
          • 2018-10-10
          • 2015-09-05
          • 2018-01-09
          • 1970-01-01
          • 2017-09-29
          相关资源
          最近更新 更多