6

'daki sütun veri türüyle eşleştirmek için gelen verilerin veri türünü değiştirmek için `BEFORE INSERT 'tetikleyicisini kullanarak, türünde numaralı bir sütuna sahip bir postgres tablom var. Bu tabloya veri eklemek için kullanıcılar COPY kullanıyor. Ancak bazen T türünde olmayan bir C değeri eklemeyi dener, ancak bu değeri T.PostgreSQL

dönüştürebilecek bir postgres işlevine sahip olurum. Tabloda bir BEFORE INSERT tetikleyici yazmaya çalışıyorum. Ekleme türü hataları almadığımdan emin olmak için verilerde bu işlevi çağır. Ancak işe yaramazsa, verileri tetiklemeye çalışırken, hatta oradaki tetikleyici ile bile hata alıyorum. Ben araştıran çok fazla zaman harcamak önce

, bu mümkün olup olmadığını öğrenmek istiyorum. Gelen verilerin türünü değiştirmek için bu şekilde tetikleyiciler kullanabilir miyim?

bu postgresql 9.3 yayınlanmasını istediğiniz ama postgres 9.5 hata ve çalışmayan tetiği fark etmiş.

+0

ama var [kuralları] denediniz mi (http://www.postgresql.org/docs/current/static/rules.html)? – Kevin

cevap

4

Hayır, bu yaklaşımı kullanamazsınız. Bunun nedeni, arka uçun, bir kaydı tabloya eklenecek değerlerle doldurmasıdır. Bu, tetikte bulunan NEW parametresi biçimindedir. Bu nedenle, tetik tetiklenmeden önce bile hata atılır. Onun yorumunda Kevin'in önerisi çalışmaz böylece

aynı, tesadüfen, kurallara için de geçerlidir.

Muhtemelen en iyi çözüm "müsamahakar" sütunu veri türleri (örneğin text gibi) ve ardından son koymadan önce kendi doğru türe tüm sütun değerlerini atmalarını bu tabloda bir BEFORE INSERT tetiği koymak ile bir evreleme tablo oluşturmaktır tablo. Bu ikinci ekleme başarılı olursa, satırdan tabloya gitmeyecek şekilde RETURN NULL'u bile ekleyebilirsiniz (bununla ilgili olarak, COPY bunun hakkında ne düşünüyor ...). Tabloda yer alan bu kayıtların bazı garip verileri vardır ve daha sonra bu satırlarla manuel olarak ilgilenebilirsiniz. Patrick bunu işlemek için bir şans önce Postgres doğrulama verilerini reddetmek kalmaması bir müsamahakâr hedef belirtmek zorunda belirtildiği gibi

5

.

ikinci tablosu olmadan bir başka yolu, varchar için her şeyi atmalarını Baz masada bir görünüm oluşturmak ve sonra bir ekleme görünüm üzerinde çalışılmıştır zaman baz tablo doldurur bir INSTEAD OF tetikleyici sahip olmaktır.

Örnek olarak, tablo tab1 altında bir tamsayı sütunu bulunmaktadır. Görünüm v_tab1'in bir varchar'ı vardır, böylece herhangi bir insert görünüm için çalışacaktır. Tetik yerine, girilen değerin sayısal olup olmadığını ve bunun yerine 0 değerini kullanıp kullanmadığını kontrol eder. Şimdi

create table tab1 (i1 int, v1 varchar); 

create view v_tab1 as select cast(i1 as varchar) i1, v1 from tab1; 

create or replace function v_tab1_insert_trgfun() returns trigger as 
$$ 
declare 
    safe_i1 int; 
begin 
    if new.i1 ~ '^([0-9]+)$' then 
    safe_i1 = new.i1::int; 
    else 
    safe_i1 = 0; 
    end if; 

    insert into tab1 (i1, v1) values (safe_i1, new.v1); 
    return new; 
end; 
$$ 
language plpgsql; 

create trigger v_tab1_insert_trigger instead of insert on v_tab1 for each row execute procedure v_tab1_insert_trgfun(); 

ekler de

|i1 |v1 | 
+-----+-----+ 
|12 |hello| 
|0 |world| 

Fiddle verilmesi değeri

insert into v_tab1 values ('12','hello'); 
insert into v_tab1 values ('banana','world'); 
select * from tab1; 

bakılmaksızın çalışır: http://sqlfiddle.com/#!15/9af5ab/1 Bu işe yarayıp bana net değil