PostgreSQL:如何在函数的 CASE 表达式中使用 SELECT 语句?

Mee*_*eem 5 postgresql case plpgsql

我们可以在函数的 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;
Run Code Online (Sandbox Code Playgroud)

--调用函数

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*/
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 3

实际上,有一个plpgsqlCASE语句,不要与SQLCASE表达式混淆:

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;
Run Code Online (Sandbox Code Playgroud)
  • 如果您将函数声明为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;
Run Code Online (Sandbox Code Playgroud)

相同的结果。同样快。SQL 或 PL/pgSQL 函数取决于品味和其他一些细节。PL/pgSQL 对于独立调用可能更快。SQL可以更容易地嵌套。