SQL Tetikleyicileri Hakkında Bilmeniz Gerekenler
Trigger, veritabanında belirli tablolarla ilişkilendirilmiş ve bazı işlemler gerçekleştiğinde kendiliğinden devreye giren otomatik bir mekanizmadır. Bir kayıt eklendiğinde, değiştirildiğinde ya da...
Trigger, veritabanında belirli tablolarla ilişkilendirilmiş ve bazı işlemler gerçekleştiğinde kendiliğinden devreye giren otomatik bir mekanizmadır. Bir kayıt eklendiğinde, değiştirildiğinde ya da silindiğinde, bu işlemleri takip ederek ilgili SQL komutlarını arka planda çalıştırır.
İçindekiler
Örneğin, yeni bir veri eklendiği anda tarih bilgisini otomatik kaydetmek ya da veri bütünlüğünü sağlamak için belirli kuralları uygulamak amacıyla kullanılabilir. Bu sayede uygulama tarafında ekstra işlem yazmaya gerek kalmaz.
Tetikleyicinin Çalışma Mantığı
Veritabanında CREATE TRIGGER komutu ile oluşturulan ve belirli bir tabloya bağlanan otomatik yapılardır. Bu yapılar, tanımlanan bir işlem gerçekleştiğinde devreye girer ve etkilenen her satır için ayrı ayrı çalışır.
Bir tetikleyici tanımlanırken bazı temel unsurlar belirlenir. Öncelikle tetikleyicinin işlemden önce mi yoksa sonra mı çalışacağı (BEFORE/AFTER) seçilir. Ardından hangi işlemle tetikleneceği (INSERT, UPDATE veya DELETE) belirlenir ve hangi tabloya bağlı olacağı ifade edilir. Son olarak çalıştırılacak SQL komutları, BEGIN ve END blokları içinde yazılır.
Örneğin, tabloya veri eklenmeden hemen önce çalışan bir BEFORE INSERT tetikleyicisi ya da veri güncellendikten sonra devreye giren bir AFTER UPDATE tetikleyicisi oluşturulabilir. MySQL’de bu yapıların her satır için ayrı ayrı çalışabilmesi adına FOR EACH ROW ifadesinin kullanılması zorunludur.
Trigger içinde veriyle çalışırken NEW ve OLD anahtar kelimeleri kullanılır. Yeni eklenen veriye INSERT işlemlerinde NEW ile erişilirken, silinen veriye DELETE işlemlerinde OLD ile ulaşılır. UPDATE işlemlerinde ise hem eski hem de yeni değerleri karşılaştırmak mümkündür; OLD önceki durumu temsil ederken, NEW ise güncellenmiş hali temsil etmektedir.
Söz dizimi aşağıdaki şekildedir:
CREATE TRIGGER tetikleyici_adı
BEFORE|AFTER {INSERT|UPDATE|DELETE} ON tablo_adı
FOR EACH ROW
BEGIN
-- SQL kodunu yazacağımız kısım --
END;
Bu yapı, SQL’de yaygın olarak kullanılan standart gösterim biçimidir. Ancak burada gözden kaçmaması gereken önemli bir detay vardır: trigger içinde birden fazla SQL komutu bulunabildiği için, noktalı virgül işareti normal komut sonlandırıcı olarak karışıklığa yol açabilir. Bu sorunu önlemek amacıyla, CREATE TRIGGER ifadesi yazılmadan önce delimiter değeri çoğu zaman değiştirilir. Örneğin, ayırıcı geçici olarak // yapılabilir; böylece tüm trigger bloğu sistem tarafından tek parça halinde doğru biçimde okunur.
Tetikleyici Oluşturma Adımları
- Adım) Bunun için basit bir kullanıcı tablosu hazırlayarak başlıyoruz
CREATE TABLE kullanicilar(
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(60),
created_at DATETIME,
updated_at DATETIME
);
- Adım) Ayırıcıyı Değiştirme SQL’de, çoklu ifade tetikleyicileri yazabilmek için ifade ayırıcısını değiştirebilirsiniz.
DELIMITER // - Adım) CREATE TRIGGER Deyimini Yazın
Örneğin, ekleme sırasında created_at sütununu geçerli zamana ayarlayan bir tetikleyici oluşturabiliriz:
CREATE TRIGGER kayit_oncesi_user
BEFORE INSERT ON kullanicilar
FOR EACH ROW
BEGIN
IF NEW.created_at IS NULL THEN
SET NEW.created_at = NOW();
END IF;
END;
Bu kod örneğinde yer alan BEFORE INSERT ON kullanicilar ifadesi, tetikleyicinin tabloya yeni bir kayıt eklenmeden hemen önce devreye gireceğini gösterir.
Tetikleyici içerisinde, NEW.created_at alanının boş olup olmadığı kontrol edilir. Eğer bu alan null ise, NOW() fonksiyonu kullanılarak otomatik şekilde mevcut zaman değeri atanır. Böylece kayıt oluşturulurken zaman bilgisinin manuel girilmesine gerek kalmaz.
Trigger tanımlaması tamamlandıktan sonra, istenirse delimiter eski ayarına döndürülerek diğer SQL komutlarının sorunsuz çalışması sağlanabilir.
- Adım) Tetikleyiciyi Test Etmek
Bundan sonra, created_at değeri belirtilmeden bir ekleme yapıldığında, bu alan tetikleyici tarafından otomatik şekilde atanacaktır.
INSERT INTO kullanicilar (username) VALUES ('Çağatay');
SELECT * FROM kullanicilar;
Böylece created_at alanı, güncel tarih ve saat ile kendiliğinden doldurulur. Tetikleyiciler, varsayılan değerler tanımlayarak işlemleri otomatikleştirmeye yardımcı olur.
Trigger Türleri Nelerdir?
Her tablo için toplamda altı farklı SQL tetikleyici (trigger) türü bulunur:
- BEFORE INSERT Trigger (Eklemeden önce çalışır)
- BEFORE UPDATE Trigger (Güncellemeden önce çalışır)
- BEFORE DELETE Trigger (Silmeden önce çalışır)
- AFTER INSERT Trigger (Eklemeden sonra çalışır)
- AFTER UPDATE Trigger (Güncellemeden sonra çalışır)
- AFTER DELETE Trigger (Silmeden sonra çalışır)
Şimdi bu tetikleyici türlerini örnekler üzerinden tek tek inceleyelim.
1. BEFORE INSERT Trigger
Bu tetikleyici, tabloya yeni bir kayıt eklenmeden hemen önce devreye girer. Çoğunlukla, veri kaydedilmeden önce kontrol etmek veya gerekli düzenlemeleri yapmak için kullanılır.
BEFORE INSERT için örnek SQL tetikleyici söz dizimi:
CREATE TRIGGER kayit_oncesi_user
BEFORE INSERT ON kullanicilar
FOR EACH ROW
BEGIN
SET NEW.created_at = NOW();
END;
Bu tetikleyici, yeni bir kullanıcı kaydı eklenmeden önce created_at zaman damgasını güncel tarih ve saatle otomatik olarak ayarlar.
2. BEFORE UPDATE Trigger
Bu tetikleyici, var olan bir kayıt güncellenmeden hemen önce devreye girer. Güncelleme yapılmadan önce veriyi doğrulamak ya da gerekli değişiklikleri uygulamak için kullanılır.
BEFORE UPDATE için örnek SQL tetikleyici söz dizimi:
DELIMITER //
CREATE TRIGGER guncelleme_oncesi_user
BEFORE UPDATE ON kullanicilar
FOR EACH ROW
BEGIN
IF NEW.email NOT LIKE '%@%' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Geçersiz e-posta adresi';
END IF;
END;
DELIMITER ;
Bu tetikleyici, kullanıcı kaydı güncellenmeden önce girilen yeni e-posta adresinin geçerliliğini denetler; geçersiz olması durumunda ise hata verir.
3. BEFORE DELETE Trigger
Bu tetikleyici, bir kayıt silinmeden hemen önce devreye girer. Aynı zamanda, belirli şartlarda silme işlemini engellemek veya veri bütünlüğünü korumak için de kullanılabilir.
BEFORE DELETE için örnek SQL tetikleyici söz dizimi:
DELIMITER //
CREATE TRIGGER siparisi_silmeden_once
BEFORE DELETE ON siparisler
FOR EACH ROW
BEGIN
IF OLD.status = 'Teslim Edildi' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Teslim edilen siparişler silinemiyor!';
END IF;
END;
DELIMITER ;
Bu tetikleyici, sevk edilmiş (gönderilmiş) siparişlerin silinmesini önler.
4. AFTER INSERT Trigger
Bu tetikleyici, yeni bir satır eklendikten sonra devreye girer ve çoğunlukla kayıt tutma (loglama) ya da ilgili tabloları güncelleme amacıyla kullanılır.
AFTER INSERT için örnek SQL tetikleyici söz dizimi:
CREATE TRIGGER after_yeni_kullanici
AFTER INSERT ON kullanicilar
FOR EACH ROW
BEGIN
INSERT INTO user_logs(user_id, action, log_time
VALUES (NEW.id, 'User created', NOW());
END;
Bu tetikleyici, yeni bir kullanıcı oluşturulduğunda bu durumu user_logs tablosuna kayıt altına alır.
5. AFTER UPDATE Trigger
Bu tetikleyici, bir satır güncellendikten sonra devreye girer. Yapılan değişiklikleri izlemek veya bağlantılı verileri güncellemek için kullanılır.
AFTER UPDATE için örnek SQL tetikleyici söz dizimi:
CREATE TRIGGER after_kullanici_guncelle
AFTER UPDATE ON kullanicilar
FOR EACH ROW
BEGIN
INSERT INTO user_logs(user_id, action, log_time)
VALUES (NEW.id, CONCAT('User updated: ', OLD.name, ' to ', NEW.name), NOW());
END;
Bu tetikleyici, bir kullanıcının adında yapılan değişikliği güncelleme sonrasında kayıt altına alır.
Bu tetikleyici, bir kullanıcının silinme işlemini user_log tablosuna kayıt altına alır.
Trigger Ne Zaman ve Neden Kullanılır?
Tetikleyiciler, veriler üzerinde bir değişiklik gerçekleştiğinde belirli işlemleri otomatik olarak yürütmek için oldukça etkili yapılardır. Aşağıda, SQL trigger’ların hangi durumlarda tercih edildiğini ve sağladığı avantajları özgün bir şekilde inceleyebilirsin:
Tekrarlayan İşlerin Otomatik Hale Getirilmesi:
Zaman damgası, sayaç veya hesaplanan alanlar gibi değerleri uygulama tarafında ekstra kod yazmadan otomatik olarak oluşturabilirsin. Örneğin, created_at ve updated_at gibi alanlar her işlemde kendiliğinden güncellenebilir.
Veri Doğruluğunu ve Kuralları Koruma:
Tetikleyiciler, belirlenen şartları kontrol ederek hatalı veri girişlerini engelleyebilir. Örneğin, bir BEFORE INSERT tetikleyicisi kurallara uymayan bir kaydı sisteme almadan durdurabilir. Bu da veri kalitesinin korunmasına yardımcı olur.
Değişikliklerin İzlenmesi (Loglama):
Veri üzerinde yapılan işlemleri otomatik olarak kayıt altına almak mümkündür. Örneğin, bir kayıt silindiğinde AFTER DELETE tetikleyicisi devreye girerek bu işlemi bir log tablosuna yazabilir. Böylece geçmiş işlemler kolayca takip edilebilir.
Tablolar Arası Senkronizasyon Sağlama:
Bir tabloda yapılan değişikliğin başka tabloları da etkilemesi gereken durumlarda tetikleyiciler devreye girer. Bu sayede ilişkili veriler arasında uyum korunur ve güncellemeler arka planda otomatik olarak gerçekleştirilir.
Performans ve Sınırlamalar
Tetikleyiciler güçlü araçlardır ancak dikkatli kullanılmaları gerekir. Çünkü veri üzerinde her değişiklikte otomatik olarak çalışırlar. Fazla sayıda veya karmaşık trigger kullanımı sistemi yavaşlatabilir ve hataları bulmayı zorlaştırabilir. Buna rağmen; zaman damgası ekleme, veri doğrulama veya tablolar arası veri uyumunu sağlama gibi işlemlerde oldukça işe yararlar. Aynı işlemleri tekrar tekrar kodlamak yerine süreci otomatikleştirerek hem zaman kazandırır hem de hata riskini azaltır.
Trigger kullanmadan önce şu noktaları göz önünde bulundurmak önemlidir:
Arka Planda Çalışan Mantık:
Tetikleyiciler veritabanı içinde tanımlıdır ve otomatik şekilde çalışır. Bu durum, sistemde neler olup bittiğini anlamayı zorlaştırabilir. Geliştiriciler, verinin arka planda değiştirildiğini gözden kaçırabilir. Bu yüzden trigger’ların iyi şekilde belgelenmesi gerekir.
Transaction Yönetimi Kısıtı:
Trigger içerisinde bağımsız bir transaction başlatılamaz, commit ya da rollback işlemleri yapılamaz. Tüm işlemler, tetikleyiciyi tetikleyen sorgunun transaction’ı içinde gerçekleşir. Bu nedenle trigger içinde kısmi bir işlemi onaylayıp devam etmek mümkün değildir.
Transaction Desteklemeyen Yapılar:
Eğer transaction desteklemeyen bir tablo motoru kullanılıyorsa, trigger sırasında oluşan hatalarda tüm değişiklikler geri alınamayabilir. Bu da veri bütünlüğünü bozabilecek durumlara yol açabilir.
Kısıtlı İşlem Yeteneği:
Trigger’lar bazı SQL işlemlerini gerçekleştiremez. Örneğin, DDL komutları çalıştırılamaz veya sonuç döndüren bazı prosedürler kullanılamaz. Ayrıca view (görünüm) üzerinde trigger tanımlamak mümkün değildir.
Tekrarlı Çalışma (Recursion) Sınırlaması:
Trigger’lar kendi kendini sonsuz şekilde tetikleyecek bir yapı kuramaz. Yani aynı tabloyu sürekli güncelleyerek döngü oluşturulmasına izin verilmez. Bu nedenle, sürekli kendini tetikleyen senaryolardan kaçınılmalıdır.
SQL trigger’lar ilk başta biraz kafa karıştırıcı gelebilir, bu çok normal ama işin içine girdikçe mantığını çözüyorsun ve aslında ne kadar işini kolaylaştırdığını fark ediyorsun. Çünkü tabloda bir değişiklik olduğunda kendi kendine çalışıyor; sen ekstra uğraşmadan hem zaman kazanıyorsun hem de verinin kurallara uygun kalmasını sağlıyorsun.
İster yapılan değişiklikleri kaydetmek olsun, ister hatalı güncellemeleri engellemek ya da tablolar arasında uyumu sağlamak… Trigger’lar bu işlerde gerçekten kurtarıcı oluyor. Ama burada önemli bir nokta var: abartmamak. Çok fazla trigger kullanırsan işler karışabiliyor ve sonradan hatayı bulmak zorlaşabiliyor.
Kısacası, sade tut, güzelce test et ve kontrollü kullan. Bu şekilde trigger’lardan maksimum verimi alacağına emin olabilirsin.
İlgili makaleyi inceleyebilirsin:
Henüz yorum yok! İlk yorumu siz yapın.