database - RETURN 不能在带有 OUT 参数的函数中有参数

标签 database postgresql plpgsql

我做了从 oracle 到 pgsql 的数据库迁移,得到了如下代码:

CREATE OR REPLACE FUNCTION PKG_UTIL_BD_LOGISTICS_getsignerinfo (
  i_opCode T_MQ_LOGIC_TRACK_HEAD_LOG.LP_CODE%TYPE, i_remark T_MQ_LOGIC_TRACK_HEAD_LOG.REMARK%TYPE, i_acceptTime T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE, i_signer T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE, i_lpcode T_MQ_LOGIC_TRACK_HEAD_LOG.LP_CODE%TYPE,
  o_signer OUT T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE, o_signerTime OUT T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE, o_status OUT T_MQ_LOGIC_TRACK_HEAD_LOG.STATUS%TYPE ) 
RETURNS RECORD AS $body$
DECLARE

  v_signer        T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNER%TYPE;
  v_signerTime    T_MQ_LOGIC_TRACK_HEAD_LOG.SIGNED_TIME%TYPE;
  v_status        T_MQ_LOGIC_TRACK_HEAD_LOG.STATUS%TYPE;

BEGIN
IF i_lpcode = 'SF' THEN
   IF i_opCode = '8000' THEN
      IF POSITION(':back' in i_remark) > 0 THEN
        v_status := '3';
      ELSE
        v_status := '7';
        v_signerTime := i_acceptTime;
        v_signer := SUBSTR(i_remark, POSITION(':' in i_remark) + 1);
      END IF;
  ELSIF i_opCode = '9999' THEN
      v_status := '3';
    ELSIF i_opCode = '80' THEN
      v_status := '7';
      v_signerTime := i_acceptTime;
    ELSIF i_opCode = 70 THEN
      v_status := i_opCode;
    ELSE
      v_status := '1';
    END IF;
ELSE
  IF i_opCode = 'signed' THEN
      v_signerTime := i_acceptTime;
      v_signer := i_signer;
      v_status:='7';
  ELSE
    v_status:='1';
  END IF;

END IF;
  o_status := v_status;
  o_signer := v_signer;
  o_signerTime := v_signerTime;
  RETURN 1;
EXCEPTION
  WHEN OTHERS THEN
    RAISE EXCEPTION '%', 'PKG_UTIL_BD_LOGISTICS.getSignerInfo fetch parameters' || i_remark || 'value error:' || SQLERRM;
END;

$body$
LANGUAGE PLPGSQL
SECURITY DEFINER

当我执行代码时,出现错误:RETURN 不能在带有 OUT 参数的函数中有参数。有人可以帮忙吗?我是 pgsql 的新手。

最佳答案

带有 OUT 参数的函数的结果由 OUT 参数的值指定,并且仅由这些值指定。尽管 OUT 参数的语法在 PostgreSQL 和 Oracle 之间相似,但实现方式却大不相同。

Oracle 使用 OUT 参数的引用 - 所以你可以这样写:

CREATE FUNCTION foo(a int, OUT b int)
RETURN boolean IS
BEGIN
  b := a;
  RETURN true;
END;

此函数返回 bool 值,作为“副作用”,它修改了通过引用传递的第二个参数。

PostgreSQL 不支持通过引用传递参数。所有参数仅按值传递。当您使用 OUT 参数时,没有传递引用,但返回值取自结果组合。结果组合仅由 OUT 参数组成。没有其他空间。所以代码:

CREATE OR REPLACE FUNCTION foo(a INT, OUT b int)
RETURNS boolean AS $$
BEGIN
  b := a;
  RETURN true;
END; $$ LANGUAGE plpgsql

无效,因为 foo 函数的实际结果是标量 int 值,这与声明的 bool 值相矛盾。 RETURN true 也是错误的,因为结果只是基于 OUT 参数,然后 RETURN 应该没有任何表达式。

函数 foo 从 Oracle 到 Postgres 的等价翻译是:

CREATE OR REPLACE FUNCTION foo(a INT, OUT b int, OUT result boolean)
RETURNS record AS $$
BEGIN
  b := a;
  result := true;
  RETURN;
END; $$ LANGUAGE plpgsql

简单规则 - 当函数在 Postgres 中有 OUT 变量时,RETURN 语句仅用于结束执行 - 不用于指定返回值。此值基于 OUT 参数。

关于database - RETURN 不能在带有 OUT 参数的函数中有参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45725699/

相关文章:

java - 解析 postgres 对象文字

django - 性能:在 PostgreSQL ArrayField 中存储点赞(Django 示例)

sql - 在 PgAdmin 的 Postgresql 中使用反向 for 循环反转数字

关于 PLPGSQL 的 PostgreSQL 9.1 pg_restore 错误

ruby-on-rails - 如何使用现有的 SQL 数据库将我的 Rails 应用程序部署到 Heroku?

Mysql时间错误

javascript - 使用 knex.js 在 psql 中的 CREATE FUNCTION 语句中出现语法错误

postgresql - Plpgsql 函数在创建语法处或附近出现错误

java - 检查 sqlite 中的文本

java - 关系数据未存储在 Ebean 中