2017-12-06 18 views
0

私はdb内にいくつかの関数を持っています。postgresql case inside functionはトリガーしません

特定のテーブルのデータが5分より古い場合、1つの関数を実行する必要があります。私はそれをやってみました

:私は、通常のSELECTクエリなどのコマンドを実行すると

PERFORM case when now() - '5 minutes'::interval > (select end_time from x order by end_route desc limit 1) then update_x() else null end; 

、それがOKに実行されます。しかし、別の関数(呼び出されているものが5分以上経過していない更新されたテーブルを返します)の中に入れても、決して実行されません。また、私はちょうどupdate_x()を置く場合、それはOK(ただし、関数が呼び出されるたびに)実行されます。

誰も私がこれをどのように修正できるか考えている人はいますか? 1つのアイデアは、関数を独立して5分ごとに実行するようにcronを設定することですが、この機能はかなりリソース集約的なので、サーバーはアイドル状態です。

私はバージョン8.4になっています(私のISPのため、変更することはできませんが、VPSに移行することを検討していますので、これが9.5以降で動作するものであれば待つことができます)。

+0

もう少しコンテキストなしで言うのは難しいが、注目すべき一つのことは、 'NOW()'実際には、むしろ現在の時刻を返しますが、しないことです現在のトランザクションの開始時刻。これがあなたが望むものでない場合は、代わりに 'clock_timestamp()'を試してください。詳細については、[docs](https://www.postgresql.org/docs/current/static/functions-datetime.html)を参照してください。 –

答えて

2

機能now()は、現在のトランザクションの開始時刻を示し、その内部では変更されません。 (実際の現在時刻を返します)

do $$ 
begin 
    for i in 1..3 loop 
     perform pg_sleep(1); 
     raise notice 'now(): % clock_timestamp(): %', now(), clock_timestamp(); 
    end loop; 
end $$; 

NOTICE: now(): 2017-12-06 10:22:40.422683+01 clock_timestamp(): 2017-12-06 10:22:41.437099+01 
NOTICE: now(): 2017-12-06 10:22:40.422683+01 clock_timestamp(): 2017-12-06 10:22:42.452456+01 
NOTICE: now(): 2017-12-06 10:22:40.422683+01 clock_timestamp(): 2017-12-06 10:22:43.468124+01 

(clock_timestamp

the documentation:パーので、その値は今でも、単一のSQLコマンド(...)

以内に変更されます。clock_timestamp(),例を使用します)は、transaction_timestamp()と同等の従来のPostgreSQLです。

+0

動作しません。私はまだ更新呼び出しを取得しません。現在と同じように動作します。私は定期的なクエリとしてコマンドを実行する場合、私は関数内に置く場合、それは更新されません。 – darthzejdr

+0

これは、両方の機能の完全なコードのない推測ゲームです。 'update_x()'で 'now()'を使っていますか? – klin

+0

それを動作させるために管理されています。 i now()を複数の場所で使用しますが、update_xは基本的に新しいデータをテーブルに挿入し、テーブルxのデータが5分より古いかどうかをチェックします。つまり、update_xは30秒かかるので、最初のクエリで5分間隔で長時間を取ってから、Webアプリケーション内の連続したクエリでトリガしないようにしてください。 – darthzejdr

0

私は理由は分かりませんが、一度ブール値を1レベル上に移動すると、作業を開始しました。 これで、関数内でケースクエリを実行する代わりに、関数にブール値を送り、この関数の上のビューでチェックを実行します。

CREATE VIEW x_view AS select * from get_x((clock_timestamp() - '5 minutes'::interval)::timestamp > (select end_route from gps_skole2 order by end_route desc limit 1)); 

と機能内部:

PERFORM case when $1 then update_x() else null end; 
関連する問題