【问题标题】:store all the values of a column returned by a select query in a variable - PostgreSQL将选择查询返回的列的所有值存储在变量中 - PostgreSQL
【发布时间】:2019-12-31 08:47:05
【问题描述】:

我有一张表,用于保存企业内部进行的交易记录。

现在我正在编写一个返回在表中找到的事务 ID 的函数。以下是函数代码:

CREATE OR REPLACE FUNCTION searchList(inputList varchar) RETURNS character varying AS $BODY$

DECLARE
newList varchar;
rowcount integer;
splitted varchar[];

BEGIN
splitted = regexp_split_to_array(inputList,','); --splits the string by comma as a delimiter and produces an array as a result

select incidents.transaction_id into newList from incidents where transaction_id IN(select unnest(splitted)); --unnest function expands the array and is replaced by all the values of array

GET DIAGNOSTICS rowcount = ROW_COUNT; -- ROW_COUNT is the literal which is gonna provide the number of rows returned by previous query

IF rowcount = 0 THEN
return 'Match does not exist';
ELSE
return newList;
END IF;
END;
$BODY$ LANGUAGE plpgsql;

我提供一个字符串作为函数的输入,然后将该字符串拆分为一个数组,然后我运行一个选择查询,该查询旨在将所有此类记录的事务 id 存储到一个其事务 id 为的变量中存在于数组中,最后返回变量

但是,当我执行此函数时,即使提供的所有 transaction_id 都是匹配的,我也只会得到一个 transaction_id 作为输出。

我正在使用 select into 将结果存储到变量中,但是我感觉它只存储列的一个极值(第一个/最后一个)

有什么方法可以将可能包含多个条目的单个列的结果存储到变量中。

我知道这里已经有多个与 select into 相关的线程,但是它们都没有帮助。我最近开始使用 pgsql,所以对这个主题知之甚少

【问题讨论】:

  • @a_horse_with_no_name 我的不好,它是 9.4,即使那是古老的,但这与我们正在使用的应用程序捆绑在一起

标签: plpgsql postgresql-9.4 select-into


【解决方案1】:

如果你想返回所有返回的值,你需要以某种方式聚合。由于您似乎想要一个逗号分隔的列表,请使用 string_agg()。不过,不需要取消嵌套数组:

CREATE OR REPLACE FUNCTION searchlist(inputlist text) 
  RETURNS text AS 
$BODY$
DECLARE
  newlist text;
BEGIN
  select string_agg(transaction_id,',')
     into newlist 
  from incidents 
  where transaction_id = any (string_to_array(inputlist, ','));

  IF coalesce(newlist, '') = '' THEN
    return 'Match does not exist';
  ELSE
    return newList;
  END IF;
END;
$BODY$ 
LANGUAGE plpgsql;

我强烈建议不要传递逗号分隔值。 Postgres 正确支持数组,我将使用数组作为参数,并将数组作为返回值。您也不需要为此使用 PL/pgSQL。

更简洁的版本(在我看来)是:

CREATE OR REPLACE FUNCTION search_list(p_inputlist int[]) 
  RETURNS int[]
AS 
$BODY$
  select array_agg(transaction_id)
  from incidents 
  where transaction_id = any (p_inputlist);
$BODY$ 
LANGUAGE sql;

唯一的区别是它不会返回一条消息,表明返回的数组是空的。如果这样做,您可以在使用该函数检查是否没有返回行的代码中使用cardinality()

【讨论】:

  • 非常感谢!您提供的脚本有效:) 我也会通过更清洁的版本来看看。由于我在 postgres 中执行,我曾经认为 LANGUAGE 作为 sql,我需要将其设置为 plpgsql,感谢提供新信息。只是想了解它有什么区别?如果所有逻辑都使用通用 sql 命令,将 SQL 作为语言编写是否会提供更好的速度/效率?
猜你喜欢
  • 1970-01-01
  • 2012-06-04
  • 2017-06-26
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
相关资源
最近更新 更多