5

PostgreSQL には、一括収集を使用して Oracle のようにステートメントを作成する方法がいくつかありますか?

Oracle での例:

create or replace procedure prc_tst_bulk_test is

type typ_person is table of tb_person%rowtype;
v_tb_person typ_person;

begin

select *
bulk collect into v_tb_person
from tb_person;

-- make a selection in v_tb_person, for instance    
select name, count(*) from v_tb_person where age > 50
union 
select name, count(*) from v_tb_person where gender = 1

end;

ありがとうございました

4

4 に答える 4

5

PostgreSQL にはそのような構文はなく、機能的に同等のものもありません。

PL/PgSQL コードで一時テーブルを作成し、それを目的に使用できます。名前がセッション内でグローバルであるため、PL/PgSQL の一時テーブルは少し面倒ですが、PostgreSQL 8.4 以降では正しく機能します。

単一の SQL ステートメント内ですべての作業を行う場合のより良い代替手段は、共通のテーブル式 (CTE、またはWITHクエリ) を使用することです。これはすべての状況に適しているわけではありません。

上記の例はRETURN QUERY、PL/PgSQL で簡単に解決する方がはるかに優れていますが、実際の例はもっと複雑だと思います。

これが、ユニオンの各ブランチでスキャンするだけでなく、生成するのにコストがかかるある種のビューであると仮定するとtb_person、次のようにすることができます。

CREATE OR REPLACE FUNCTION prc_tst_bulk()
RETURNS TABLE (name text, rowcount integer) AS 
$$
BEGIN
    RETURN QUERY
    WITH v_tb_person AS (SELECT * FROM tb_person)
    select name, count(*) from v_tb_person where age > 50
    union 
    select name, count(*) from v_tb_person where gender = 1;
END;
$$ LANGUAGE plpgsql;

この特定のケースは、単純な SQL 関数にさらに単純化できます。

CREATE OR REPLACE FUNCTION prc_tst_bulk()
RETURNS TABLE (name text, rowcount integer) AS 
$$
    WITH v_tb_person AS (SELECT * FROM tb_person)
    select name, count(*) from v_tb_person where age > 50
    union 
    select name, count(*) from v_tb_person where gender = 1;
$$ LANGUAGE sql;
于 2013-04-30T00:08:02.297 に答える