2011-07-07 24 views
2

rep_eventというPostgresテーブルの1つに、各行がいつ挿入されたかを示すtimestamp列があります。しかし、すべての行のタイムスタンプ値は2000-01-01 00:00:00なので、何かが正しく設定されていません。関数内でnow()を呼び出す

行をテーブルに挿入する関数があり、それはそのテーブルに行を挿入する唯一のコードであり、他のコードはそのテーブルに挿入されません。 (また、そのテーブルの行を更新するコードがありません。)ここでは関数の定義である:ここで

CREATE FUNCTION handle_event() RETURNS "trigger" 
AS $$ 
BEGIN 
    IF (TG_OP = 'DELETE') THEN 
     INSERT INTO rep_event SELECT 'D', TG_RELNAME, OLD.object_id, now(); 
     RETURN OLD; 
    ELSIF (TG_OP = 'UPDATE') THEN 
     INSERT INTO rep_event SELECT 'U', TG_RELNAME, NEW.object_id, now(); 
     RETURN NEW; 
    ELSIF (TG_OP = 'INSERT') THEN 
     INSERT INTO rep_event SELECT 'I', TG_RELNAME, NEW.object_id, now(); 
     RETURN NEW; 
    END IF; 
    RETURN NULL; 
END; 
$$ LANGUAGE plpgsql; 

テーブル定義されています

CREATE TABLE rep_event 
(
operation character(1) NOT NULL, 
table_name text NOT NULL, 
object_id bigint NOT NULL, 
time_stamp timestamp without time zone NOT NULL 
) 

あなたが見ることができるように、現在時刻を取得するためにnow()関数が呼び出されます。データベース上で「今すぐ選択」()を実行すると正しい時刻が返されるため、関数内からnow()を呼び出す際に問題がありますか?

CREATE TABLE rep_event (
    operation character(1) NOT NULL, 
    table_name text NOT NULL, 
    object_id bigint NOT NULL, 
    time_stamp timestamp without time zone NOT NULL DEFAULT NOW() 
); 

その後、あなたは(今を取り除くことができます)あなたのトリガーに呼び出します。

+0

トリガー定義を表示できますか?どんなテーブルに結びついていますか? – Flimzy

+1

非常に奇妙です。関数の中で 'now()'を呼び出すのに問題はありません。他にもいくつか問題があると思います。 BTWは、作成/修正タイムスタンプであることを意図しているならば、 "タイムゾーン付きのタイムスタンプ"(直感的ではないが、そうである)であるべきであり、 'now()'ではなく 'CURRENT_TIMESTAMP'しかし、これは必須ではありません。 – leonbloy

答えて

4

簡単な解決策は、単にデフォルト値を()今持っているあなたのテーブル定義を変更することです。

また、私はあなたの関数に列の順序を含めることを強くお勧めします... IOW;あなたは今までに新しい列を追加したり、テーブルの内部順序を変更する他のテーブルの変更を行う場合

INSERT INTO rep_event (operation,table_name,object_id,time_stamp) SELECT ... 

この方法で、あなたの関数が突然中断されません。

1

あなたの問題は他の場所になければなりません。機能はうまくいきます。テスト・データベースを作成し、あなたが引用したコードを貼り付けして実行します。

create table events (object_id bigserial, data text); 
create trigger rep_event 
    before insert or update or delete on events 
    for each row execute procedure handle_event(); 

insert into events (data) values ('v1'),('v2'),('v3'); 
delete from events where data='v2'; 
update events set data='v4' where data='v3'; 

select * from events; 
  object_id | data 
    -----------+------ 
      1 | v1 
      3 | v4 
select * from rep_event; 
  operation | table_name | object_id |   time_stamp   
    -----------+------------+-----------+---------------------------- 
    I   | events  |   1 | 2011-07-08 10:31:50.489947 
    I   | events  |   2 | 2011-07-08 10:31:50.489947 
    I   | events  |   3 | 2011-07-08 10:31:50.489947 
    D   | events  |   2 | 2011-07-08 10:32:12.65699 
    U   | events  |   3 | 2011-07-08 10:32:33.662936 
    (5 rows) 

チェック他のトリガー、トリガーの作成コマンドなどとtimestamp with timezoneにこのtimestamp without timezoneを変更します。

関連する問題