2016-03-30 14 views
5

yerine gerçekleşmişse NASILPostgres - CONFLICT - Bir GÜNCELLEME INSERT

CREATE TABLE foo 
(
    f0 int, 
    time_stamp timestamp, 
    CONSTRAINT foo_pk PRIMARY KEY (f0) 
) 

Ben yüksek hacimlerde bu tabloyla yazmaya gerek bir tablo var biliyorum, bu yüzden performans anahtarıdır. Bazen, f0 için varolan bir değere sahip bir kayıt yazacağım ve şimdiki zamana time_stamp güncelleyecektir. Bunun için bir ON CONFLICT..DO UPDATE kullanın.

sorunu, bir INSERT'un veya UPDATE'un olup olmadığını bilmem gerekmesidir.

İkinci bir is_update sütununu kullanıyorum. yerleştirirken, false takıp

`ON CONFLICT .. DO UPDATE set is_update=true` 

Sonra İstediğimi elde etmek RETURNING is_update kullanın. Bununla ilgili sorun, verilerin kendisiyle ilgili olmayan ek bir sütunun tanıtılmasıdır.

+0

[bir Upsert PostgreSQL 9.5+ Upsert ile bir güncelleme olup olmadığını öğrenmek için nasıl?] (Http: //stackoverflow.com/questions/34762732/how-to-find-out-if-an-upsert-was-an-update-with-postgresql-9-5-upsert) – lad2025

+0

@ lad2025 Bu soruyu daha önce bulamadınız mı, Teşekkürler. Bununla birlikte, önerilen çözüm denediğimi söylediğim şeydi, ancak bu "UPSERT/ON CONFLICT" özelliğinden yoksun olduğumu hissettiğim bazı işlevler için masamdaki ek sütun nedeniyle kaçınmak isterim. – Sagi

+0

[PostgreSQL Upsert, sistem sütunlarını XMIN, XMAX ve diğerlerini kullanarak eklenen ve güncelleştirilen satırları ayırt eder] (https://stackoverflow.com/q/39058213/1995738) – klin

cevap

0

Foo tablosunda tetikleme işlevi oluşturabilirsiniz. Ardından, anahtar mevcutsa, insert numaralı işi TG_OP ayrılmış kelimeyle yakalayın, aksi takdirde yeni bir satır ekleyin.

CREATE OR REPLACE FUNCTION public.f0_update_on_duplicate() 
RETURNS trigger 
LANGUAGE plpgsql 
AS $function$ 
declare _exists boolean; 
begin 
    if TG_OP = 'INSERT' then 
    select exists(select true from foo where f0 = NEW.f0) into _exists; 
    raise notice '%', _exists; 
    if _exists = TRUE then 
     update foo set time_stamp = NEW.time_stamp where f0 = NEW.f0; 
     return NULL; 
    else 
     return NEW; 
    end if; 
    end if; 
end 
$function$; 

2.Attach prosedürü tabloları foo:

CREATE TRIGGER update_on_duplicate 
BEFORE INSERT ON foo FOR EACH ROW EXECUTE PROCEDURE 
f0_update_on_duplicate(); 

3.DENEME insert henüz büyük sıralar :)

1.Create prosedürü ile test edilmedi. Bu (foo tablolar bulunmaktadır assumming f0 = 5'tir) yeni TIME_STAMP'de ile F0 güncellemek gerekir:

INSERT INTO foo (f0, time_stamp) VALUES (5, now());