假设我有:CREATE TYPE compfoo AS (f1 int, f2 text);
我创建了一个表foo
,它包含两列:foid和fooname,对应于compfoo的字段,稍后我插入了一些记录1, aa
、2, bb
、3, cc
然后,我定义了一个PL/pgSQL函数(大致如下所示:)
create or replace function foo_query()
returns text
language plpgsql
as $$
declare
r compfoo;
arr compfoo [];
footemp compfoo;
result text;
begin
for r in
select * from foo where fooid = 1 OR fooid = 2
loop
arr := array_append(arr, r);
end loop;
foreach footemp in array arr
loop
select footemp.f1 into result where footemp.f1 = 1;
end loop;
return result;
end;
$$
在这里,我首先通过列名查询foo
,并将结果保存到arr
(compfoo的数组)中。随后,我遍历arr
,并尝试通过compfoo中定义的字段名查询元素。
我在Postgres中本身没有得到错误,但我的函数的结果是空的。
我做错了什么?
1条答案
按热度按时间brgchamk1#
RAISE NOTICE
应该是你最好的朋友。你可以在代码的某些地方打印一些变量的结果。基本的问题是没有很好地初始化值。arr
变量是由NULL
值初始化的,任何对NULL
的操作都是NULL
。另一个问题是
select footemp.f1 into result where footemp.f1 = 1;
语句。Postgres中的SELECT INTO
在结果为空时用NULL
值覆盖目标变量。在第二次迭代中,该查询的结果为空集,并且result
变量设置在NULL
上。你的例子中最大的问题是编程风格。你使用 *ISAM风格 *,你的代码可能会非常慢。
array_append
,当查询中可以使用array_agg
函数,并且不需要循环时,SELECT INTO
,您的固定代码可能如下所示:
它返回了预期的结果。但它是一个完美的例子,说明了如何不写存储过程。不要试图替换存储过程中的SQL。这个过程的所有代码都可以用一个查询来替换。最后,这个代码在处理较大的数据时会非常慢。