Menu

SQLite Trigger Kullanımı: CREATE TRIGGER, OLD/NEW

SQLite trigger'ları nasıl çalışır? BEFORE, AFTER, view'lar için INSTEAD OF, OLD ve NEW satır referansları ve trigger'ı ne zaman tercih etmeli — hepsi örneklerle.

Bu sayfada çalıştırılabilir editörler var — düzenle, çalıştır ve sonucu anında gör.

SQLite Trigger Otomatik Olarak SQL Çalıştırır

SQLite trigger, belirli bir tabloda belirli bir olay gerçekleştiğinde otomatik olarak tetiklenen, kayıtlı bir SQL bloğudur. Bir kere yazarsınız, "ne zaman çalışacağını" SQLite senin yerine takip eder.

Genel yapı şöyle:

Burada price_history tablosuna elle bir INSERT yazmadık. İşi tetikleyici hallediyor. Bundan sonra fiyat ne zaman güncellense — ister CLI'dan, ister bir script'ten, ister bir uygulamadan gelsin — kayıt aynı şekilde tutulacak.

CREATE TRIGGER söz diziminin anatomisi

Sözdizimini parça parça inceleyelim:

CREATE TRIGGER trigger_name
{ BEFORE | AFTER | INSTEAD OF } { INSERT | UPDATE [ OF column_list ] | DELETE }
ON table_name
[ FOR EACH ROW ]
[ WHEN condition ]
BEGIN
    -- bir veya daha fazla ifade
END;
  • ZamanlamaBEFORE değişiklikten önce, AFTER sonra çalışır; INSTEAD OF ise işlemin yerine geçer (yalnızca view'larda).
  • Olay — tetikleyiciyi hangi işlem çalıştırır. UPDATE OF col1, col2 yazarsanız tetikleyici sadece belirtilen sütunlardaki güncellemelerde devreye girer.
  • Tablo — izlenen tablo.
  • FOR EACH ROW — SQLite yalnızca satır bazlı tetikleyicileri desteklediği için bu zaten varsayılandır. Okunaklılık için yazabilirsiniz, davranışı değiştirmez.
  • WHEN — opsiyonel bir koşul. Gövde yalnızca bu koşul doğruysa çalışır.
  • GövdeBEGIN ile END arasına yazılan bir veya daha fazla ifade. Her ifadenin sonunda noktalı virgül olmalı.

Söz dizimi bundan ibaret. Pratikte gördüğünüz tetikleyicilerin çoğu beş ila on satır arasındadır.

OLD ve NEW: Değişen satıra erişim

Gövdenin içinde, veriye erişmenizi sağlayan iki sözde satır vardır:

  • NEW — gelen satır. INSERT ve UPDATE tetikleyicilerinde kullanılabilir.
  • OLD — mevcut satır. UPDATE ve DELETE tetikleyicilerinde kullanılabilir.

DELETE tetikleyicisinde yalnızca OLD, INSERT tetikleyicisinde yalnızca NEW bulunur. UPDATE tetikleyicisinde ise her ikisi de mevcuttur.

Silinen satır artık accounts tablosunda yok, ama kaybolmadan önce verisi deletions tablosuna düşmüş bile.

BEFORE: Satırı Doğrula veya Düzelt

BEFORE trigger'ları, satır değişikliği diske yazılmadan önce çalışır. Hata fırlatmak ya da veriyi normalleştirmek için biçilmiş kaftandır:

İkinci INSERT, tek bir satır bile yazılmadan iptal ediliyor. RAISE(ABORT, '...') çağrısı o anki ifadeyi iptal edip başlangıcına geri sarar. Daha ince ayar lazımsa RAISE(FAIL, ...), RAISE(ROLLBACK, ...) ve RAISE(IGNORE) seçenekleri elinizin altında.

Sadece veri doğrulaması yapacaksanız CHECK kısıtlarını tercih edin — bildirimseldirler ve optimize edici onları tanır. BEFORE trigger'ına ise kuralın başka tablolara bakması ya da CHECK'in ifade edemeyeceği bir iş yapması gerektiğinde başvurun.

WHEN: Koşullu sqlite Trigger'ları

WHEN koşulu, hangi satır değişikliklerinin trigger gövdesini gerçekten tetikleyeceğini filtreler. Her satır için, OLD ve NEW bağlandıktan sonra değerlendirilir:

İlk sipariş eşiği geçmiyor. Diğer ikisi geçiyor. WHEN koşulu olmasaydı her ekleme big_orders tablosuna da yazılır, filtrelemeyi okuma tarafında yapmak zorunda kalırdınız.

INSTEAD OF: View'i Yazılabilir Hale Getirme

View'ler varsayılan olarak salt okunurdur. INSTEAD OF trigger'ı, view üzerinde yapılan bir yazma işlemini yakalar ve onun yerine sizin yazdığınız SQL'i çalıştırır — genelde bu işlemi alttaki tablolara yapılan yazmalara çevirir:

Uygulama, view ile sanki normal bir tabloymuş gibi konuşur. Arka planda first_name ve last_name ayrımını ise trigger halleder.

Trigger'ları Listeleme ve Silme (sqlite drop trigger)

Trigger'lar; tablolar ve indeksler gibi sqlite_master tablosunda tutulur:

DROP TRIGGER IF EXISTS name; güvenli kullanım şeklidir. Trigger'ın bağlı olduğu tabloyu sildiğinizde trigger da otomatik olarak silinir; önceden temizlik yapmanıza gerek yoktur.

Bilmekte Fayda Var: Sık Düşülen Tuzaklar

İlk kez trigger yazanları zorlayan birkaç nokta var:

  • Trigger'lar her satır için ayrı ayrı çalışır, ifade başına değil. 1.000 satırı etkileyen bir UPDATE, trigger'ı 1.000 kez tetikler. Trigger gövdesi ağır iş yapıyorsa bu hızla birikir.
  • Trigger'lar içinde bulundukları transaction kapsamında çalışır. Dıştaki ifade rollback olursa trigger'ın yazdıkları da geri alınır. Çoğu zaman istediğiniz davranış budur ama "ne olursa olsun bunu logla" amacıyla trigger kullanamayacağınız anlamına da gelir.
  • Özyinelemeli (recursive) trigger'lar varsayılan olarak kapalıdır. Aynı tabloyu değiştiren bir trigger, PRAGMA recursive_triggers = ON; ayarı yapılmadıkça kendini yeniden tetiklemez. Belirli bir gerekçeniz yoksa kapalı bırakın.
  • Uygulama tarafındaki yazımlar trigger'ları atlayabilir, ama bu ancak veritabanını es geçtiğinizde olur. Tüm yazma işlemleri SQLite üzerinden geçtiği sürece trigger çalışır. Ham SQL ile toplu işlem yapan ORM'ler bile trigger'ları tetikler.
  • İş mantığını birçok trigger'a dağıtmayın. Çağrı noktasından görünmezler — "bu satır nereden geldi?" diye debug eden biri sqlite_master içinde grep yapmak zorunda kalır. Trigger'ları kesişen sorumluluklar için kullanın (audit log, türetilmiş kolonlar, view'a yazılabilirlik kazandırma); gerisini uygulama kodunda tutun.

Gerçekçi Bir Audit-Log Örneği

Şimdi tüm bu kalıpları birleştirelim — posts tablosundaki her değişikliği takip edelim:

Tek bir trigger, hem updated_at alanını güncel tutar hem de tek bir noktadan denetim (audit) kaydı yazar. UPDATE sorgusunu çalıştıran uygulama kodunun bu işlerden haberi bile olmaz.

Sıradaki Konu: JSON Desteği

Trigger'lar, satır seviyesindeki olayların otomasyonunu üstlenir. SQLite'ın bir sonraki ileri seviye konusu ise satırın içine ne koyabileceğinizle ilgili: JSON. SQLite, yapılandırılmış veriyi sorgulamak ve güncellemek için SQL'den çıkmadan kullanabileceğiniz eksiksiz bir JSON fonksiyon seti sunuyor — bir sonraki sayfada tam olarak buna bakacağız.

Sıkça Sorulan Sorular

SQLite'ta trigger nedir?

Trigger, bir tabloda belirli bir olay (INSERT, UPDATE veya DELETE) gerçekleştiğinde otomatik çalışan bir SQL bloğudur. CREATE TRIGGER ile bir kez tanımlarsınız, sonrasında SQLite bu olay her tetiklendiğinde sizin yerinize çalıştırır. Audit kayıtları tutmak, türetilmiş kolonları güncel tutmak veya iş kurallarını uygulamak için uygulamaya güvenmek zorunda kalmadan kullanabilirsiniz.

BEFORE, AFTER ve INSTEAD OF trigger'ları arasındaki fark nedir?

BEFORE satır değişikliği uygulanmadan önce çalışır — doğrulama yapmak veya satırı düzenlemek için idealdir. AFTER ise değişiklik gerçekleştikten sonra çalışır; loglama veya başka tabloları senkronize etme gibi işler için biçilmiş kaftandır. INSTEAD OF yalnızca view'larda çalışır ve asıl yapılacak işlemin yerine geçer; böylece view'ı yazılabilir hâle getirebilirsiniz.

Trigger içinde değişen satıra nasıl erişirim?

INSERT ve UPDATE sırasında gelen satır için NEW.kolon, UPDATE ve DELETE sırasında mevcut satır için OLD.kolon kullanırsınız. INSERT trigger'ları sadece NEW'i, DELETE trigger'ları sadece OLD'u görür; UPDATE trigger'ları ise her ikisine de erişebilir. Bu referanslar yalnızca o anda işlenmekte olan satıra aittir.

SQLite'ta trigger'ları nasıl listeler veya silerim?

Trigger'lar sqlite_master tablosunda tutulur — SELECT name, tbl_name FROM sqlite_master WHERE type = 'trigger'; sorgusuyla hepsini görebilirsiniz. Silmek için DROP TRIGGER trigger_adi; veya var olup olmadığından emin değilseniz DROP TRIGGER IF EXISTS trigger_adi; kullanın. Bir tabloyu sildiğinizde ona bağlı trigger'lar da otomatik silinir.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA