如何将存储在记录类型变量中的查询结果用于同一存储函数中的另一个查询?我使用Postgres 9.4.4.

有这样一张桌子:

create table test (id int, tags text[]);
insert into test values (1,'{a,b,c}'),
                        (2,'{c,d,e}');

我编写了一个函数(简化),如下所示:

CREATE OR REPLACE FUNCTION func(_tbl regclass)
RETURNS TABLE (t TEXT[], e TEXT[])
LANGUAGE plpgsql AS $$
DECLARE
  t RECORD;
  c INT;
BEGIN
  EXECUTE format('SELECT id, tags FROM %s', _tbl) INTO t;
  SELECT count(*) FROM t INTO c;
  RAISE NOTICE '% results', c;
  SELECT * FROM t;
END
$$;

... 但没有奏效:

select func('test');
ERROR:  42P01: relation "t" does not exist
LINE 1: SELECT count(*) FROM t
                             ^
QUERY:  SELECT count(*) FROM t
CONTEXT:  PL/pgSQL function func(regclass) line 7 at SQL statement
LOCATION:  parserOpenTable, parse_relation.c:986

推荐答案

核心误解是:record变量包含single行(或NULL),而不是表(0-n行的已知类型).有no "table variables" in Postgres or PL/pgSQL个.根据任务的不同,有多种 Select :

因此,不能将multiple行分配给record类型变量.在本声明中:

EXECUTE format('SELECT id, tags FROM %s', _tbl) INTO t;

... 博士后分配only the first row名学生,其余学生放弃.因为"第一个"在查询中没有很好的定义,所以最终会出现任意 Select .显然是因为一开始提到的误解.

在SQL查询中,record变量也不能用来代替表.这是导致错误的主要原因:

关系"t"不存在

现在应该很清楚,count(*)一开始就没有任何意义,因为t只是一个记录/行——而且无论如何都是不可能的.

最后(即使剩下的也行),您的返回类型似乎是错误的:(t TEXT[], e TEXT[]).既然你在t中 Select 了id, tags,你会想要返回(id int, e TEXT[])这样的值.

你想做什么would work like this:

CREATE OR REPLACE FUNCTION func(_tbl regclass)
  RETURNS TABLE (id int, e text[]) AS
$func$
DECLARE
   _ct int;
BEGIN
   EXECUTE format(
      'CREATE TEMP TABLE tmp ON COMMIT DROP AS
       SELECT id, tags FROM %s'
    , _tbl);

   GET DIAGNOSTICS _ct = ROW_COUNT; -- cheaper than another count(*)

   -- ANALYZE tmp;  -- if you are going to run multiple queries

   RAISE NOTICE '% results', _ct;

   RETURN QUERY TABLE tmp;
END
$func$ LANGUAGE plpgsql;

拨打(note the syntax!):

SELECT * FROM func('test');

相关的:

只是概念的证明. Select 整个表时,只需使用基础表即可.实际上,查询中会有大约WHERE个子句...

小心潜在的类型不匹配,count()返回bigint,不能将其分配给integer变量.需要一个演员阵容:count(*)::int.

但我完全取代了它,在EXECUTE岁之后立即运行它更便宜:

GET DIAGNOSTICS _ct = ROW_COUNT; 

Details in the manual.

为什么是ANALYZE


旁白:纯SQL中的CTE通常可以完成以下任务:

Postgresql相关问答推荐

带有regex表达式的Postgres SQL

包含JSONB属性的过滤器的索引策略

用于JSON数组的带有组合条件的Postgres JSONB Select 查询

为什么Postgres在打印时能完全缩短时间跨度?

使用PythonPolar在PostgreSQL中存储

Select 与输入数组完全相交的所有行?

我想优化查询SQL

查找行中的最小值

Cloud SQL 时间点 数据驻留

如何在 postgresql 上使用 sqlalchemy 进行正确的 upsert?

Rails:安装 pg gem 时出错

将 PostgreSQL 配置为仅适用于 LOCALHOST 或指定的 ip + 端口

在函数中返回字段作为插入结果

在 postgresql 中,如何在 jsonb 键上返回布尔值而不是字符串?

在同一分区上应用多个窗口函数

设置 Phoenix 框架和 Ecto 以使用 UUID:如何插入生成的值?

如何使用 psql 执行 *.sql 文件

获取全文搜索配置语言的完整列表

在 OS X 上使用 Postgres.app 时如何将 psql 放在路径上?

Ruby 中 DateTime 的毫秒分辨率