2011-08-23 11 views
3

PostgreSQLでは、SQL文が実際に実行されるため、SQL文全体を実行せずにdctUpdate関数を呼び出す必要があるテーブルに対してUPDATE規則があります。関数。PSQL:関数呼び出しの出力をサイレンシングするか、SELECTなしで呼び出す

create or replace function infoUpdate(windowId in numeric) returns void as $$ 
begin 
    if windowId is null then 
     update info_timestamp set timestamp = now(); 
    else 
     update info_timestamp set timestamp = now() where window_id = windowId; 
    end if; 
end; 
$$ LANGUAGE plpgsql; 


create or replace rule info_update_rule as on update to some_table do also select infoUpdate(NEW.window_id); 

しかし、私はsome_table内の行を更新しているため、そのルールがトリガされますコマンドライン上で、私が呼び出すSELECT句からの無駄な出力を得る:私は関数を呼び出すの知っている唯一の方法は、SELECT dctUpdate(windowId)ています機能:

db=# update some_table set name = 'foobar' where window_id = 1; 
infoupdate 
----------- 

(1 row) 

UPDATE 1 

info_update_rule呼び出し、それがダミー出力を表示せずにinfoUpdate機能を持たせる方法はありますか?

+0

新しい 'window_id'だけがNULLの場合、テーブル全体のタイムスタンプを' now() 'に設定するのは本当ですか? PostgreSQLのどのバージョンをサポートする必要がありますか? –

+0

@mu:はい、NULLの場合はすべてのタイムスタンプを設定し、PostgreSQL 9.0以降をサポートすることを意味します。 – Fred

答えて

1

ルールを使用してこれを実装するオプションは見つかりませんでしたが、このようなトリガーを実装する別の方法があります。

だから、あなたは次のようにトリガ機能を定義します。

CREATE OR REPLACE FUNCTION ur_wrapper_trg() 
    RETURNS trigger AS 
$BODY$ 
begin 
    perform infoUpdate(NEW.window_id); 
    RETURN NEW; 
end; 
$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION ur_wrapper_trg() OWNER TO postgres; 

PERFORM構文が使用されています。この構文は、SELECT構文と同じですが、すべての出力を抑制する点が異なります。

あなたが最後にトリガー

CREATE TRIGGER some_table_utrg 
    BEFORE UPDATE 
    ON some_table 
    FOR EACH ROW 
    EXECUTE PROCEDURE ur_wrapper_trg(); 

を定義するよりも、あなたはあなたのルールをremve。

nullでテストされていませんが、実際にはwindos_idが正常に動作し、不要な出力はありません。

詳しくは、TriggersおよびRules vs triggersにお問い合わせください。

+0

パフォーマンス上の理由からトリガーを使用することはできません。このルールは、ミッションクリティカルなシステム上で数千の行を更新するクエリに適用され、これらの行のそれぞれに対してトリガーを呼び出すのは非常に高価になるため、ルールで行う必要があります。私はまだパフォーマンスのヒットを得るためにガベージ出力を取得することを好む。 – Fred

0

私が来た解決策は\t \aの前にselect function()の直前に電話することです。唯一残っているのは、各通話のための新しい回線です。

関連する問題