我如何使用存储在一个记录类型变量中的查询结果,在同一个存储函数中进行另一个查询?我使用Postgres 9.4.4。
有这样一张table:
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
$$;
......但不起作用:
一个二个一个一个
2条答案
按热度按时间ccrfmcuu1#
核心误区:一个
record
变量只保存一行(或者为NULL),而不是一个表(0-n行,类型已知)。Postgres或PL/pgSQL中没有"表变量"。根据任务的不同,有多种选择:因此,不能将***多个***行赋给
record
类型变量。在此语句中:... Postgres只分配 * 第一行 * 并丢弃其余的行。由于"第一行"在查询中没有很好地定义,所以您最终会得到一个任意的选择。显然是由于开头提到的误解。
record
变量也不能用来代替SQL查询中的表,这是导致错误的主要原因:关系"t"不存在
现在应该很清楚了,
count(*)
一开始就没有任何意义,因为t
只是一个记录/行-而且无论如何都是不可能的。最后(即使剩下的也行),你的返回类型似乎是错误的:
(t TEXT[], e TEXT[])
。因为您选择id, tags
到t
,所以您希望返回类似(id int, e TEXT[])
的内容。您尝试执行的操作将如下所示:
调用**(注意语法!)**:
相关:
这只是一个概念证明。当您选择整个表时,您只需使用底层表。实际上,您将在查询中使用一些
WHERE
子句...注意潜在的类型不匹配,
count()
返回bigint
,你不能把它赋给integer
变量。count(*)::int
.但是我完全替换了它,在
EXECUTE
之后运行它更便宜:手册中的详细信息。
为什么是
ANALYZE
?旁白:普通SQL中的CTE通常可以完成这项工作:
u2nhd7ah2#
以下是我在红移数据库中使用plpgsql中RECORD类型变量的几种方法
1.运行循环
1.存储记录变量
代码类型1
代码类型2