处理错误“记录或行变量不能成为多项INTO列表的一部分”

时间:2017-10-20 17:03:30

标签: plpgsql

这种“解决方法”是否有“更清晰”的语法?

我有以下对象可供使用:

create type token as(tp varchar(20), val varchar(128));
create or replace
function p_post_token
         (      token_type varchar,
         ,inout token_new  token
         ,inout tokens_all token[]
         ,  out b1         boolean
         ,  out b2         boolean
         ,  out b3         boolean
         ) as...

该函数有一些(长)逻辑,但最终是:

  1. 根据某些条件修改“新”记录,
  2. 将“新”记录添加到“所有”数组
  3. 清空“新”记录,
  4. 设置一些布尔输出。
  5. 当我按如下方式调用我的函数时(来自Oracle PL / SQL的转换):

    do $$
    declare
      lb1 boolean;
      lb2 boolean;
      lb3 boolean;
      --
      lr_token  token;
      lt_tokens token[];
    begin
      select * into lr_token, lt_tokens, lb1, lb2, lb3
        from p_post_token('', lr_token, lt_tokens);
    end$$;
    

    我收到错误:

    ERROR:  record or row variable cannot be part of multiple-item INTO list
    LINE 10:       select * into lr_token, lt_tokens, lb1, lb2, lb3
    

    我建议的解决方法是:

    do $$
    declare
      lb1 boolean;
      lb2 boolean;
      lb3 boolean;
      --
      lr_token  token;
      lt_tokens token[];
      --
      r record;
    begin
      select * into r
        from p_post_token('', lr_token, lt_tokens);
      lr_token  := r.token_new;
      lt_tokens := r.tokens_all;
      lb1       := r.b1;
      lb2       := r.b2;
      lb3       := r.b3;
    end$$;
    

    这可行,但我必须在个地方调用函数p_post_token,而且这样的代码“太长了”。

    这是从INOUT / OUT记录参数+其他INOUT / OUT参数读取函数输出的唯一方法吗?是(希望)有“一线”的方法吗?

2 个答案:

答案 0 :(得分:0)

没有任何可能通过一个声明做你要求的事情。这个限制是由于一些较旧的实现而无法更改,因为PostgreSQL开发人员不应该破坏兼容性。记录类型的解决方法是可能的。

答案 1 :(得分:0)

我的一位同事建议(恕我直言)更容易/更好的解决方法。将record参数转换为数组。函数声明将变为:

function p_post_token
     (      token_type varchar
     ,inout token_new  token[] --<< this turned from record to array
     ,inout tokens_all token[]
     ,  out b1         boolean
     ,  out b2         boolean
     ,  out b3         boolean
     ) as...

...让代码(内部)只处理数组中的一条记录。 这样可以避免在处理记录时出现大量“额外”代码。

对函数的调用然后变成一个单行(直截了当,直观,再次恕我直言):

do $$
declare
  lb1 boolean;
  lb2 boolean;
  lb3 boolean;
  --
  lr_token  token[];
  lt_tokens token[];
begin
  select * p_post_token('', lr_token, lt_tokens)
    into lr_token, lt_tokens, lb1, lb2, lb3;
end$$;

我希望这可以帮助那些正在努力解决问题的人。

干杯!