2016-05-10 3 views
1

タイムテーブルを監査テーブルに記録するPL/pgSQL関数を作成しました。 しかし、PostgresSQLの文キャッシュでは、 呼び出しごとにnow()が再計算されないため、古い(古い)タイムスタンプが監査テーブルに記録されています。PostgreSQLステートメントのキャッシングが期待される結果を妨げる

私たちはPostgres 9.2を実行しています。ドキュメント http://www.postgresql.org/docs/9.2/static/plpgsql-implementation.html#PLPGSQL-PLAN-CACHING(記事の末尾までスクロール)によれば、now()へのコールに頼ることが推奨されています。予想通り

この機能は動作しません:

CREATE OR REPLACE FUNCTION save(txd integer) RETURNS void AS $$ 
BEGIN 
    INSERT INTO audit (id, mtime) VALUES (txd,now()); 
END;$$ 

として定義されたテーブルで:psycopg2を使用して簡単なのpython 2.7のスクリプトは、問題を実証するために使用することができます

CREATE TABLE audit (
    id integer NOT NULL, 
    mtime timestamp without time zone NOT NULL, 
    CONSTRAINT audit_pkey PRIMARY KEY (id) 
) 

import datetime, psycopg2, time 
def tm(): 
    # connect and clear contents 
    con = psycopg2.connect('dbname=postgres user=postgres') 
    cur = con.cursor() 
    cur.execute('TRUNCATE audit') 

    # Add a record, wait a second, add another 
    cur.execute('SELECT save(1)') 
    time.sleep(1.0) 
    cur.execute('SELECT save(2)') 

    # List the contents 
    cur.execute('SELECT * FROM audit') 
    for row in cur.fetchall(): 
     print("modified %s" % row[1]) 
    cur.close() 
    con.close() 

このスクリプトを実行すると、2つのインスタンスo fは、我々はのINSERT

>>> tm() 
modified 2016-05-10 11:05:21.766005 
modified 2016-05-10 11:05:21.766005 

注の間に小さな1秒のスリープを挿入していても、時間が正確に同じ値を報告します修正:私たちもリンクされ 記事中のpostgresによって提供された例を試してみました。例を使用して出力に差はありません。

CREATE OR REPLACE FUNCTION save(txd integer) RETURNS void AS $$ 
DECLARE 
    curtime timestamp; 
BEGIN 
    curtime = 'now'; 
    INSERT INTO audit (id, mtime) VALUES (txd,curtime); 
END;$$ 

ここで間違っている場所で誰かが私たちを真っ直ぐに立てることができますか?

+1

は '今()'タイムスタンプを返す必要があります。実際の時間をサブトランストランザクションレベルにしたい場合は、 'clock_timestamp()'が必要です。http://www.postgresql.org/docs/9.5/static/functions-datetime.html – joop

+0

ありがとう!あなたがこれを答えさせたら、私は授与されます。 – user590028

答えて

0

now()は、トランザクション開始時にタイムスタンプを返します。;これにより、トランザクション内のすべてのクロック読み取り値が同じ値(これはしばしばあなたが望むもの)になります。あなたは、サブトランザクション・レベルで実際の時間が必要な場合

、あなたは**始めるトランザクションで** clock_timestamp()http://www.postgresql.org/docs/9.5/static/functions-datetime.html

関連する問題