我们能否在函数中使用CASE条件表达式中的SELECT语句?
我尝试了以下功能来完成上述任务。
示例:我有一个用于显示包含某些行的表的函数。
create or replace function test(n integer)
returns table (name text,city text) as
$body$
begin
case n when 1 then
select * from table1
when 2 then
select * from table2
when 3 then
select * from view1
end;
end;
$body$
language plpgsql;
- 调用功能
select * from test(1);
/*have to show details of table1*/
select * from test(2);
/*have to show details of table2*/
select * from test(3);
/*have to display details of view1*/
答案 0 :(得分:2)
为此,您需要IF
语句和RETURN QUERY
,例如
create or replace function test(n integer)
returns table (name text,city text) as
$body$
begin
IF n = 1 THEN
RETURN QUERY select * from table1;
ELIF n = 2 THEN
RETURN QUERY select * from table2;
ELIF n = 3 THEN
RETURN QUERY select * from view1;
END IF;
end;
$body$
language plpgsql;
但是,这是一件非常奇怪的事情。
答案 1 :(得分:2)
实际上,有一个plpgsql CASE
statement,不要与SQL CASE
expression混淆:
CREATE OR REPLACE function test(n integer)
RETURNS TABLE (name text, city text) AS
$func$
BEGIN
CASE n
WHEN 1 THEN
RETURN QUERY SELECT t.name, t.city FROM table1 t;
WHEN 2 THEN
RETURN QUERY SELECT t.foo, t.bar FROM table2 t;
WHEN 3 THEN
RETURN QUERY SELECT t.bar, t.bamm FROM view1 t;
END CASE;
END
$func$ LANGUAGE plpgsql;
如果将函数声明为RETURNS TABLE (name text, city text)
,那么SELECT语句应该具有匹配类型的列列表。
另一方面,如果您想要SELECT *
,请相应地将该函数声明为RETURNS SETOF table1
。
在返回类型中命名列时,这些变量在函数体中可见。请确保对与同名冲突的列名进行表限定。所以t.name
而非name
。
函数内部查询的列名在外部不可见。只有声明的返回类型。因此,名称不必匹配,只需要匹配数据类型。
无论哪种方式,我建议简化一些事情:
CREATE OR REPLACE function test(n integer)
RETURNS SETOF table1 AS
$func$
SELECT * FROM table1 t WHERE n = 1
UNION ALL
SELECT * FROM table2 t WHERE n = 2
UNION ALL
SELECT * FROM view1 t WHERE n = 3;
$func$ LANGUAGE sql;
结果相同。同样快。 SQL或PL / pgSQL函数是一个品味和其他一些细节问题。对于独立调用,PL / pgSQL可能更快。 SQL可以更容易嵌套。