Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL:如何在函数的CASE表达式中使用SELECT语句?_Postgresql_Case_Plpgsql - Fatal编程技术网

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

PostgreSQL:如何在函数的CASE表达式中使用SELECT语句?,postgresql,case,plpgsql,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

我们能在函数的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*/

为此,您需要一个
IF
语句和
返回查询,例如:

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;
然而,想做这件事是一件非常奇怪的事情。

事实上,有一件事是不可混淆的:

  • 如果将函数声明为返回表(名称文本、城市文本)
,则SELECT语句应具有具有匹配类型的列列表。
另一方面,如果希望
选择*
,则将函数声明为
相应地返回表1的集合

  • 在返回类型中命名列时,这些变量在函数体中可见。确保表限定与相同名称冲突的列名。因此,
    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可以更容易地嵌套。

    还有一个问题,如果我想显示与上面返回表具有不同列名的表2行,那么如何显示它。如果你想问其他问题,请发布一个新问题;堆栈溢出尝试每个问题只保留一个主要主题。好的,我们会处理它。非常感谢。这里有点混乱。UNION ALL需要所有列都相同,但是当我想显示一个具有不同列的表时,这里可以吗?@Meem:列的数量及其日期类型必须匹配(或者在密切相关的类型之间可以自动转换)。或者,您必须填写常量并强制转换以使它们匹配。函数也是如此。对于
    联合
    查询,只使用第一个分支的名称,而
    联合
    查询后面分支中的名称并不无关。对于函数,只使用声明的
    返回
    类型的名称。
    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;