İşlemin içeriği (yani, silme veya basit silme) bir yerde saklanmalıdır. Bu amaç için özel bir parametre kullanabilirsiniz. , tetikleyiciler aşağıdaki sırayla ateş edilir gerçekleştirilir (tablodan tbl1
itibaren) silin basamaklı Ne zaman: masanın tbl1
üzerine
trigger before delete on tbl1
trigger before delete on tbl2
trigger after delete on tbl1
trigger after delete on tbl2
Sen (öncesi ve silme sonra) bu nedenle iki tetikleyiciler ihtiyaç ve bir tetikleyici önce masada tbl2
silme .
tbl1
'da iki tetikleyici oluşturun. tetik önce fonksiyonunda on
özel parametresini ve sonra tetikleme fonksiyonunda off
için:
create or replace function tbl1_trigger_before_delete()
returns trigger language plpgsql as $$
begin
set tbl1.cascade to on;
return old;
end $$;
create or replace function tbl1_trigger_after_delete()
returns trigger language plpgsql as $$
begin
set tbl1.cascade to off;
return null;
end $$;
create trigger tbl1_trigger_before_delete
before delete on tbl1
for each row execute procedure tbl1_trigger_before_delete();
create trigger tbl1_trigger_after_delete
after delete on tbl1
for each row execute procedure tbl1_trigger_after_delete();
tbl2
tetik fonksiyonu parametrenin mevcut değerini kontrol edin.
create or replace function tbl2_trigger_before_delete()
returns trigger language plpgsql as $$
begin
begin
if current_setting('tbl1.cascade') = 'on' then
raise notice 'cascaded';
else
raise exception '';
end if;
exception when others then
raise notice 'not cascaded';
end;
return old;
end $$;
create trigger tbl2_trigger_before_delete
before delete on tbl2
for each row execute procedure tbl2_trigger_before_delete();
Testi:
insert into tbl1 values
(1, '1'),
(2, '2');
insert into tbl2 values
(1, 1, '1'),
(2, 1, '2'),
(3, 2, '3'),
(4, 2, '4');
delete from tbl1 where id = 1;
NOTICE: cascaded
NOTICE: cascaded
DELETE 1
delete from tbl2 where owner = 2;
NOTICE: not cascaded
NOTICE: not cascaded
DELETE 2
Alternatif bir çözüm parametre henüz yerleştirilmemiş durumda durum blok gereklidir.
tetik önce masada tbl2
üzerinde silmek silme tanı değeri PG_EXCEPTION_CONTEXT bazı dizeye ayarlanır basamaklanmasını bağlamında yürütülür ve sil cascaded değilken o boş: Bu çözüm
create or replace function tbl2_trigger_before_delete()
returns trigger language plpgsql as $$
declare
context text;
begin
begin
raise exception '';
exception when others then
GET STACKED DIAGNOSTICS context := PG_EXCEPTION_CONTEXT;
end;
if context = '' then
raise notice 'not cascaded';
else
raise notice 'cascaded';
end if;
return old;
end $$;
create trigger tbl2_trigger_before_delete
before delete on tbl2
for each row execute procedure tbl2_trigger_before_delete();
Bu anlamda sadece testlerden kaynaklandığı sorgulanabilir olabilir, bu davranış herhangi bir yerde belgelenmez.
Merhaba klin, ilk almak için ayrıntılı ile analiz etmek, açıklamak kullanmak gerekir
Çözüm "çalışıyor" ama tam olarak istediğim şey değildi. Belki yeterince açık değildim, ama yazdığım kelle yorumunda bunu nasıl çözeceğimi biliyordum (birden çok tetikleyici kullanarak), ama Postgresql'in bu türden bir bilgi olup olmadığını bilmek istedim (alıntı), bilgiyi bir yerde saklayamazdım Daha sonra kullanmak için. Bilgileriniz için (PG_EXCEPTION_CONTEXT ile) ikinci denemem MacOSX'umda Postgres 9.4'ü çalıştırıyor, belki de sizin fark ettiğiniz belgelenmiş davranışların yan etkisidir. – Ciaccia
Anladım. Aslında ek yorumlarınızı kaçırdım. İkinci seçenek olarak, çözümü Postgres 9.4'te de test ettim. ** önce bir tetiği test ettiğinden emin misin? (Silme sonrasında tetikleme böyle bir şekilde çalışmaz). – klin
Merhaba Klin, kötüyüm, ** öncesi ** yerine ** sonra ** trigger kullanıyordum. İki durumu istisna trickini kullanarak ayırt edebilirim, sadece 'GET DIAGNOSTICS stack = PG_CONTEXT' kullanarak. Orijinal sorumu yazdığım gibi, başlangıçta bu şekilde denedim ama hiçbir şey çıkmadı (aslında tetikleme sonrası/öncesi). Bu, PG_CONTEXT'nin sadece bir ** öncesi ** tetikleyicide çalıştığı herhangi bir yerde belgelenmediği için çok kötü. Dahası, bu bana tamamen yardımcı olmuyor çünkü ** öncesi ** tetikleyici hala satırın gerçekten silinip silinmeyeceğinden emin değilim. – Ciaccia