2017-02-03 7 views
1

この質問を書いている過程で、私は答えを見つけ出して下に掲載します。この質問の重複が既にある場合は、私に通知してください、私はそれを削除します、私は何かを見つけることができませんでした。postgresのデフォルト値は、作成時だけでなく、更新時にも適用されます

created_at timestamp default now() 
updated_at timestamp 

updated_atの列は、トリガーによって更新されている:の一つの他の列があるよう

united_states_congress=> \d congressional_bill_summaries; 
             Table "public.congressional_bill_summaries" 
    Column |   Type    |         Modifiers         
-------------+-----------------------------+--------------------------------------------------------------------------- 
id   | bigint      | not null default nextval('congressional_bill_summaries_id_seq'::regclass) 
text  | text      | 
created_at | timestamp without time zone | default now() 
updated_at | timestamp without time zone | 
bill_kid | integer      | not null 
date  | date      | not null 
description | character varying(255)  | not null 
text_hash | uuid      | 
Indexes: 
    "congressional_bill_summaries_pkey" PRIMARY KEY, btree (id) 
    "congressional_bill_summaries_bill_kid_date_description_key" UNIQUE CONSTRAINT, btree (bill_kid, date, description) 
Triggers: 
    hash_all_the_things BEFORE INSERT ON congressional_bill_summaries FOR EACH ROW EXECUTE PROCEDURE hash_this_foo() 
    update_iz_yoo BEFORE UPDATE ON congressional_bill_summaries FOR EACH ROW EXECUTE PROCEDURE update_iz_now() 

私はpostgresの中のテーブルに加えられた変更を追跡する2つの列を持っている

テーブル、text_hash

私の予想される動作は、行が最初に挿入されると、created_at列がデフォルト値に更新されることです特定のクエリの時刻ではなく、現在のトランザクションが開始された時刻)。

CREATE OR REPLACE FUNCTION public.update_iz_now() 
RETURNS trigger 
LANGUAGE plpgsql 
AS $function$ 
BEGIN 
    NEW.updated_at = now(); 
    RETURN NEW; 
END; 
$function$ 

それcreated_atと、それを値が列にすでにあるので、変更されないまま、そうします:

私の予想される動作は、行が更新されたとき、updated_atのラインは、この機能によって更新されることがありますデフォルトで上書きしないでください。

のcreated_atは当初、正常に機能している:

united_states_congress=> select created_at, updated_at from congressional_bill_actions limit 5; 
     created_at   | updated_at 
----------------------------+------------ 
2017-01-28 00:08:11.238773 | 
2017-01-28 00:08:11.255533 | 
2017-01-28 00:08:15.036168 | 
2017-01-28 00:08:15.047991 | 
2017-01-28 00:08:15.071715 | 
(5 rows) 

しかし、その後の行が更新されると、created_atとは、と私を残し、updated_atのの挿入値と一致するように変更されている:

united_states_congress=> select created_at, updated_at from congressional_bill_actions where updated_at is not null limit 5; 
     created_at   |   updated_at   
----------------------------+---------------------------- 
2017-01-28 07:55:34.078783 | 2017-01-28 07:55:34.078783 
2017-02-01 18:47:50.673996 | 2017-02-01 18:47:50.673996 
2017-02-02 14:50:33.066341 | 2017-02-02 14:50:33.066341 
2017-02-02 14:50:33.083343 | 2017-02-02 14:50:33.083343 
2017-02-03 13:58:34.950716 | 2017-02-03 13:58:34.950716 
(5 rows) 

私が持っていますインターネット上でこれを理解しようとしていますが、インターネットでは、「デフォルト値の作成方法」と「トリガーを作成する方法」に関する質問に役立ちます。

これは明らかに私の目的のどこかで使用上の問題であるに違いありませんが、識別に問題があります。念のため、ここでは(挿入時)のテーブル上で実行されている他のトリガーである:この質問を書き込む処理で

CREATE OR REPLACE FUNCTION public.hash_this_foo() 
RETURNS trigger 
LANGUAGE plpgsql 
AS $function$ 
BEGIN 
    NEW.text_hash = md5(NEW.text)::uuid; 
    RETURN NEW; 
END; 
$function$ 

、私は答えを見つけて、以下のことを掲載します。この質問の重複が既にある場合は、私に通知してください、私はそれを削除します、私は何かを見つけることができませんでした。 created_atだったので

ON CONFLICT ON CONSTRAINT congressional_bill_actions_bill_kid_date_action_actor_key DO UPDATE SET created_at = EXCLUDED.created_at, 

答えて

1

問題は、ここでは、テーブルのスキーマは、このような行が含まれてクエリを動的に作成して、その結果、中に引っ張られた時に、私のUPSERT取り扱いを、でしたEXCLUDED.created_atに自動的に設定されているので、これを行うように指示していたため、既定値によって既存の値が上書きされていました。

したがって、UPSERTハンドラを書くときは、これはわかっているようです。

(注:これを避ける方法は、column_defaultがnullでない列を単にプルすることではありません)

関連する問題