Modül dersleri (3/4)
Tetikleyicilere giriş
Tetikleyici, verideki bir ekleme, güncelleme veya silme olayından ÖNCE veya SONRA otomatik olarak bir mantık parçasını çalıştıran sihirli bir kutudur (sensör).\nAncak bir tabloya tepki vermeyi öğretmeden önce, ona PL/pgSQL'de yazılmış ve "TRIGGER" adı verilen sentetik bir format döndürerek bitmesi gereken özel bir "Tetikleme Fonksiyonu" vermemiz gerekir.
Bu işlevler parantez içindeki normal bağımsız değişkenleri kabul etmez; bunun yerine sensörün izlediği tablodan orijinal veya gelen satır verilerini içeren NEW ve OLD sihirli yerleşik nesnelerini ücretsiz olarak sunarlar!
CREATE OR REPLACE FUNCTION audit_deletions()
RETURNS TRIGGER AS $$
BEGIN
-- OLD.id is magically the id value of the poor record being deleted
INSERT INTO audit_log (table_name, record_id, action)
VALUES (TG_TABLE_NAME, OLD.id, 'DELETE');
RETURN OLD; -- Triggers before a Delete route must grant the exit
END;
$$ LANGUAGE plpgsql;Bu prosedür, günlüğe yazmanın zorlu işini yapar. Daha sonra, ikinci bir adımda, korumak istediğimiz tablonun olaylarına kalıcı olarak bağlanacaktır.
Kendin dene
Müşterileri korumamız gerekiyor: 18 yaşın altındaki hiç kimse (sanal kontrolümüz) veya kurgusal mantığın ötesinde, INSERT zamanında iletilen 'first_name' dizesinin, herhangi bir JS istemci biçimlendirmesini göz ardı ederek veritabanında her zaman büyük harfle saklanmasını sağlamak istiyoruz.\n'force_uppercase_name()' adında bir Tetikleme İşlevi yazın. Hiçbir () argümanını kabul etmez.\nTRIGGER değerini döndürür. Gövde şablonunu oluşturun.\nGelen nesnenin tamamını 'YENİ.ilk_adı = UPPER(YENİ.ilk_adı);' sihirli atamasıyla zorla atayın. Daha sonra yeniden şekillendirilen YENİ değişkeni İADE EDİN.
İpucu göster
FONKSİYONU OLUŞTURUN VEYA DEĞİŞTİRİNforce_uppercase_name() TETİĞİ $$ BEGIN OLARAK GERİ DÖNÜR NEW.first_name = UPPER(NEW.first_name); YENİ DÖNÜŞ; SON; $$ DİL plpgsql;
3 denemeden sonra çözüm mevcut
Saldırganın bir üründe çok düşük bir fiyattan tasarruf etmek üzere olduğu durumlarda kötü amaçlı güncellemeleri engelleyen bir 'protect_price_drops()' Tetikleme İşlevi oluşturun.\n'IF NEW.unit_price < OLD.unit_price THEN' gibi bir mantık kullanarak her şeyin çökmesine neden olan yerel bir istisna oluşturun.\nÖlümcül bir PL/pgSQL istisnası, 'RAISE EXCEPTION ''Prezzo non abbassabile!'';' formunu kullanır.
İpucu göster
YENİ.unit_price < ESKİ.unit_price İSE BAŞLAYIN SONRA İSTİSNAYI YÜKSELTİN 'Prezzo non abbassabile!'; EĞER SON; YENİ DÖNÜŞ; SON;
3 denemeden sonra çözüm mevcut