13

「on commit drop」オプションを使用して、関数で一時テーブルを使用しています。私の問題は、場合によっては、よりグローバルな関数が最初の関数を 2 回呼び出すことができるため、コミットの前に「一時テーブルの作成」が 2 回呼び出されるため、通常のエラー「関係 [my_temp_table] が既に存在します」が発生することです。

関数の最後で一時テーブルを使用して「戻りクエリ」で行を返すため、関数を終了する前にテーブルを手動で削除することはできません。

CREATE OR REPLACE FUNCTION my_function(_value text)
RETURNS setof my_table AS $$
DECLARE 
    resultCount integer := 0;
BEGIN

    create temp table my_temp_table on commit drop as
    select *
    from my_table 
    where value = _value ;

    select count(*) into resultCount from my_temp_table;
    if (resultCount = 0) then 
        raise exception 'value not found';
        end if;

    return query
    select * from my_temp_table;

END;$$ LANGUAGE plpgsql VOLATILE COST 100;
ALTER FUNCTION my_function(text) OWNER TO postgres

直接的な方法で my_table ではなく一時テーブルを使用する理由は、非常に高速な応答が必要であり、my_table が非常に大きい (数十億行) ためです。この方法では、3 回ではなく 1 回だけ要求できます (検索、カウント、およびリターン)。

一時テーブルを使わないで型を作る回避策を見つけたのですが、my_tableの構造が何度も変わってしまい、実際に「自分のテーブル」と関連する「自分の関数」が数十個あるので、これは二度と書かない方法でしたテーブルの構造が変更されるたびに、すべての関数。

関数は、要求したテーブルと同じ構造を返す必要があります。

関数を終了するときにテーブルを削除するにはどうすればよいですか? または、より良い回避策はありますか?

4

2 に答える 2

17

...「戻りクエリ」でその行を返すため、関数を終了する前にテーブルを手動で削除することはできません。

実際にできます。あなたの場合、いくつかを使用することができRETURN QUERYます。手動の後:

PL/pgSQL 関数が SETOF [...] を返すように宣言されている場合、返される個々のアイテムは、一連の RETURN NEXT または RETURN QUERY コマンドによって指定され、引数のない最後の RETURN コマンドを使用して、関数がその関数であることを示します。実行を終了しました

したがって、次のことができます。

RETURN QUERY
       SELECT * FROM my_temp_table;
DROP TABLE my_temp_table;
RETURN;
于 2015-10-07T17:26:42.267 に答える
6

のため、テーブルを削除できます。

...
BEGIN
    drop table if exists my_temp_table;
    create temp table my_temp_table on commit drop as
    ....

しかし...実際には、一時テーブルは必要ありません。このコードを試してください:

...
    return query
    select *
    from my_table 
    where value = _value ;

    if not found then
        raise exception 'value not found';
    end if;
...
于 2015-10-07T17:25:23.033 に答える