hky*_*404 17 postgresql plpgsql postgresql-9.5
我正在尝试使用 RECORD 数据类型返回多个记录,有没有一种方法可以附加到 RECORD 并在每次迭代时向该 RECORD 添加/附加一个新值。
也就是说,我要追加到rec
使rec
成为一组行,当循环结束,我可以只返回在我的函数结束。目前,我正在这样做 -
SELECT temp_table.col1, temp_table.col2, temp_table.col3
INTO rec
FROM temp_table
WHERE temp_table.col3 = false;
Run Code Online (Sandbox Code Playgroud)
我的完整代码在这里:
CREATE OR REPLACE FUNCTION validation()
RETURNS RECORD AS $$
DECLARE
rec RECORD;
temp_row RECORD;
BEGIN
CREATE TEMPORARY TABLE temp_table (col1 TEXT, col2 INTEGER, col3 BOOLEAN) ON COMMIT DROP;
FOR temp_row IN SELECT * FROM staging.validation
LOOP
RAISE NOTICE 'sql: %', temp_row.sql;
EXECUTE format('INSERT INTO temp_table %s', temp_row.sql);
IF (SELECT DISTINCT temp_table.col3 FROM temp_table WHERE temp_table.col3 = false)=false THEN
RAISE NOTICE 'there is a false value';
SELECT temp_table.col1, temp_table.col2, temp_table.col3
INTO rec
FROM temp_table
WHERE temp_table.col3 = false;
END IF;
END LOOP;
RETURN rec;
END; $$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
后电流输出 SELECT validation();
validation
(crea_ddf,8095,f)
Run Code Online (Sandbox Code Playgroud)
期望输出
validation
(crea_ddf,8095,f)
(some_source_system,some_count,f)
(some_other_source_system,some_count,f)
(.....)
Run Code Online (Sandbox Code Playgroud)
Dan*_*ité 17
该函数需要返回一个SETOF RECORD
而不是每行RECORD
一个RETURN NEXT
而不是一个RETURN
,如下所示:
CREATE FUNCTION test() RETURNS SETOF RECORD AS $$
DECLARE
rec record;
BEGIN
select 1,2 into rec;
return next rec;
select 3,4 into rec;
return next rec;
END $$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
呼叫者:
=> select * from test() as x(a int ,b int) ; | 乙 ---+--- 1 | 2 3 | 4 (2 行)
请注意,SQL 是强类型和静态类型的,RECORD
伪类型很难使用。
通常,从一开始就使用具有每个列的名称和类型的完整定义的复合类型,无论TABLE(...)
是匿名类型的语法还是CREATE TYPE
持久命名类型的语法,都不会那么麻烦。
kli*_*lin 11
如果要从函数返回多条记录,请使用setof record
and return next rec
,例如:
create or replace function test_function()
returns setof record
language plpgsql as $$
declare
rec record;
begin
for rec in
select i, format('str%s', i), i/2*2 = i
from generate_series(1, 3) i
loop
return next rec;
end loop;
end $$;
Run Code Online (Sandbox Code Playgroud)
这样的函数需要在带有列定义列表的 FROM 子句中调用:
select test_function(); -- NO
ERROR: set-valued function called in context that cannot accept a set
select * from test_function(); -- NO
ERROR: a column definition list is required for functions returning "record"
select * from test_function() as (id int, str text, is_even boolean);
id | str | is_even
----+------+---------
1 | str1 | f
2 | str2 | t
3 | str3 | f
(3 rows)
Run Code Online (Sandbox Code Playgroud)
更好的选择是使用returns table(...)
和return query
:
drop function if exists test_function();
create or replace function test_function()
returns table (id int, str text, is_even boolean)
language plpgsql as $$
begin
return query
select i, format('str%s', i), i/2*2 = i
from generate_series(1, 3) i;
-- you can use return query multiple times
-- or assign values to columns
-- and return the row:
id = 100;
str = 'extra';
is_even = true;
return next; -- without a parameter
end $$;
Run Code Online (Sandbox Code Playgroud)
用法:
select test_function(); -- possible but rather impractical
test_function
---------------
(1,str1,f)
(2,str2,t)
(3,str3,f)
(100,extra,t)
(4 rows)
select * from test_function();
id | str | is_even
-----+-------+---------
1 | str1 | f
2 | str2 | t
3 | str3 | f
100 | extra | t
(4 rows)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
46802 次 |
最近记录: |