Sql İle Veritabanı Trigger Oluşturma Nasıl Yapılır?

Sql İle Veritabanı Trigger Oluşturma Nasıl Yapılır?
Sql İle Veritabanı Trigger Oluşturma Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

SQL triggerları kullanabilmek için modern bir ilişkisel veritabanı yönetim sistemine (RDBMS) ihtiyacınız vardır. Bu rehberde genel SQL standartlarını ve yaygın olarak kullanılan PostgreSQL ile MySQL sözdizimlerini temel alacağız. Çalışma ortamınızda şu bileşenlerin hazır olduğundan emin olun:

  • PostgreSQL 16+ veya MySQL 8.4+ sürümü kurulu bir veritabanı sunucusu.
  • Veritabanı üzerinde TRIGGER oluşturma yetkisine sahip bir kullanıcı hesabı.
  • Veritabanı işlemlerini yönetmek için bir SQL istemcisi (DBeaver, pgAdmin veya MySQL Workbench).

Başlamadan önce, üzerinde işlem yapacağımız örnek bir tablo yapısı kuralım. Senaryomuz, bir e-ticaret sistemindeki "siparişler" tablosuna yeni bir kayıt eklendiğinde "stok" tablosunu güncelleyen bir sistem üzerine kurulu olacaktır.

-- Örnek tablo yapısı
CREATE TABLE stoklar (
    urun_id INT PRIMARY KEY,
    stok_miktari INT NOT NULL
);

CREATE TABLE siparisler (
    siparis_id SERIAL PRIMARY KEY,
    urun_id INT,
    adet INT
);

Trigger Yapısı ve Temel Sözdizimi

Bir trigger oluştururken dikkat etmeniz gereken en önemli husus, tetikleyicinin işlemin "öncesinde" (BEFORE) mi yoksa "sonrasında" (AFTER) mı çalışacağıdır. BEFORE tetikleyicileri genellikle veri doğrulaması için kullanılırken, AFTER tetikleyicileri veri tutarlılığını sağlamak veya log tutmak için tercih edilir.

Aşağıdaki örnekte, bir sipariş girildiğinde stok miktarını otomatik olarak azaltan bir trigger yapısını inceleyelim:

-- PostgreSQL için örnek trigger fonksiyonu
CREATE OR REPLACE FUNCTION stok_dusur()
RETURNS TRIGGER AS $$
BEGIN
    UPDATE stoklar 
    SET stok_miktari = stok_miktari - NEW.adet
    WHERE urun_id = NEW.urun_id;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Bu kod bloğu, tetikleyici çalıştığında devreye girecek olan mantıksal fonksiyonu tanımlar. NEW anahtar kelimesi, tabloya yeni eklenen satırı temsil eder.

Adım Adım Trigger Oluşturma Uygulaması

Trigger fonksiyonunu tanımladıktan sonra, bu fonksiyonu spesifik bir tabloya ve olaya bağlamanız gerekir. İşte bir sipariş eklendiğinde tetiklenecek olan asıl tetikleyici tanımı:

-- Trigger'ı siparişler tablosuna bağlama
CREATE TRIGGER siparis_eklendikten_sonra
AFTER INSERT ON siparisler
FOR EACH ROW
EXECUTE FUNCTION stok_dusur();

Bu komut, siparisler tablosuna her yeni satır eklendiğinde, stok_dusur fonksiyonunu çalıştırır. FOR EACH ROW ifadesi, etkilenen her bir satır için işlemin tekrarlanmasını sağlar.

Trigger Yönetimi ve Karşılaştırma Tablosu

Trigger kullanırken hangi yöntemin projenize uygun olduğunu belirlemek için aşağıdaki karşılaştırma tablosunu inceleyebilirsiniz:

Özellik BEFORE Trigger AFTER Trigger
Kullanım Amacı Veri doğrulama, formatlama Loglama, ilişkili tablo güncelleme
Performans Daha hızlı (işlem öncesi) İşlem tamamlandıktan sonra
Güvenlik Veri manipülasyonuna açık Daha kontrollü

Yaygın Hatalar ve Debug İpuçları

Trigger yazarken en sık karşılaşılan hata "sonsuz döngü" (infinite loop) durumudur. Örneğin, bir tabloda güncelleme yapan bir trigger, aynı tabloyu güncelleyen başka bir trigger'ı tetiklerse sistem kilitlenebilir. Bunu engellemek için her zaman koşullu ifadeler (IF blokları) kullanın.

-- Koşullu trigger örneği (Sadece stok yeterliyse işlem yap)
CREATE OR REPLACE FUNCTION stok_kontrol_ve_dusur()
RETURNS TRIGGER AS $$
BEGIN
    IF (SELECT stok_miktari FROM stoklar WHERE urun_id = NEW.urun_id) >= NEW.adet THEN
        UPDATE stoklar SET stok_miktari = stok_miktari - NEW.adet WHERE urun_id = NEW.urun_id;
    ELSE
        RAISE EXCEPTION 'Yetersiz stok!';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Bu örnekte RAISE EXCEPTION kullanarak, stok yetersiz olduğunda işlemin tamamen geri alınmasını (rollback) sağlıyoruz.

Güvenlik Uyarısı: Triggerlar veritabanı seviyesinde çalıştığı için karmaşık mantıklar performans sorunlarına yol açabilir. Üretim ortamında (production) trigger kullanmadan önce mutlaka yük testi yapın ve SQL Injection riskine karşı veritabanı kullanıcı yetkilerini kısıtlayın.

Sıkça Sorulan Sorular

Triggerları veritabanında nasıl listelerim?

PostgreSQL'de SELECT * FROM information_schema.triggers; sorgusu ile tüm tetikleyicileri listeleyebilirsiniz.

Bir trigger'ı geçici olarak nasıl devre dışı bırakırım?

MySQL'de ALTER TABLE tablo_adi DISABLE TRIGGER trigger_adi; komutu ile tetikleyiciyi durdurabilirsiniz.

Triggerlar performans kaybı yaratır mı?

Evet, özellikle çok sayıda satırı etkileyen toplu işlemlerde (bulk insert) triggerlar ciddi performans kaybına neden olabilir. Bu durumlarda triggerları geçici olarak kapatmak en iyi pratiktir.

Aynı tabloya birden fazla trigger eklenebilir mi?

Evet, aynı olay (örneğin AFTER INSERT) için birden fazla tetikleyici tanımlayabilirsiniz; ancak bunların çalışma sırasını yönetmek karmaşık olabilir.

Trigger içerisinde başka bir veritabanına bağlanabilir miyim?

Doğrudan SQL trigger içerisinde başka bir veritabanına bağlanmak önerilmez. Bu tür işlemler için uygulama katmanında (Backend) servisler kullanmanız daha güvenlidir.

İleri Seviye Trigger Stratejileri: Audit Log Uygulaması

Veritabanı güvenliği ve denetlenebilirlik (auditing) için trigger kullanımı, endüstriyel standartlarda kritik bir rol oynar. Bir tablo üzerinde yapılan her değişikliği, kimin, ne zaman ve hangi değerle yaptığını takip etmek için ayrı bir "Log" tablosu oluşturmak en profesyonel yaklaşımdır.

Audit Log Tablosu Tasarımı

Öncelikle, değişiklikleri kaydedeceğimiz yapıyı kuralım. Bu tablo, ana tablodaki her satırın tarihçesini tutacaktır.

CREATE TABLE Personel_Log (
    LogID INT PRIMARY KEY IDENTITY(1,1),
    PersonelID INT,
    EskiMaas DECIMAL(18,2),
    YeniMaas DECIMAL(18,2),
    DegistirenKullanici VARCHAR(100),
    DegisimTarihi DATETIME DEFAULT GETDATE()
);

Dinamik Veri Takibi İçin Trigger Yazımı

Aşağıdaki trigger, Personel tablosunda bir güncelleme yapıldığında otomatik olarak devreye girer ve maaş değişikliğini log tablosuna yansıtır.

CREATE TRIGGER trg_PersonelMaasDegisim
ON Personel
AFTER UPDATE
AS
BEGIN
    IF UPDATE(Maas)
    BEGIN
        INSERT INTO Personel_Log (PersonelID, EskiMaas, YeniMaas, DegistirenKullanici)
        SELECT 
            i.PersonelID, 
            d.Maas, 
            i.Maas, 
            SYSTEM_USER
        FROM inserted i
        INNER JOIN deleted d ON i.PersonelID = d.PersonelID
        WHERE i.Maas  d.Maas;
    END
END;

Trigger Performansını Optimize Etme Teknikleri

Triggerlar, veritabanı işlemlerinin bir parçası olarak çalıştığı için, yazılan kodun verimliliği doğrudan uygulamanın hızını etkiler. Performans kaybını minimize etmek için şu kurallara dikkat edilmelidir:

  • Minimal İşlem: Trigger içerisinde ağır hesaplamalar, karmaşık JOIN işlemleri veya dış servis çağrılarından kaçının.
  • Set-Based İşlemler: Trigger içerisinde tek bir satırı işlemek yerine, inserted ve deleted tablolarını kullanarak toplu (batch) işlemleri destekleyin.
  • Koşullu Tetikleme: Trigger'ın sadece belirli sütunlar değiştiğinde çalışmasını sağlamak için IF UPDATE(sütun_adı) kontrolünü mutlaka kullanın.
  • İşlem Süresi: Trigger'ın süresi, ana işlemin (INSERT/UPDATE/DELETE) süresine eklenir. Bu yüzden trigger içindeki sorguların indekslenmiş alanlar üzerinde çalıştığından emin olun.
Uzman İpucu: Eğer çok yoğun bir yazma (write-heavy) ortamında çalışıyorsanız, veritabanı triggerları yerine "Asenkron Kuyruk" (Message Queue) sistemlerini tercih etmeyi değerlendirin. Bu, veritabanı üzerindeki yükü hafifleterek uygulamanın daha ölçeklenebilir olmasını sağlar.

Test Süreçleri ve Doğrulama

Triggerlarınızı canlıya almadan önce mutlaka bir test ortamında simüle etmelisiniz. Bir trigger'ın beklenen sonucu verip vermediğini anlamak için şu basit test senaryosunu uygulayın:

  1. Test verisi ekleyin.
  2. Trigger'ın tetikleneceği işlemi (UPDATE) gerçekleştirin.
  3. Log tablosunu SELECT * FROM Personel_Log ile sorgulayarak verilerin doğru kaydedilip kaydedilmediğini kontrol edin.
  4. Hata senaryoları için (örneğin boş değer girişi) trigger'ın nasıl tepki verdiğini gözlemleyin.

Sonuç

SQL ile veritabanı trigger oluşturma süreci, veritabanı mimarinizi güçlendiren ve veri tutarlılığını otomatize eden en güçlü araçlardan biridir. Bu rehberde öğrendiğiniz BEFORE ve AFTER tetikleyici mantığını, kendi projelerinizde loglama veya stok yönetimi gibi alanlarda güvenle kullanabilirsiniz. Bir sonraki adım olarak, veritabanı performansını izlemek için EXPLAIN ANALYZE komutlarını kullanarak yazdığınız triggerların sorgu sürelerine olan etkisini incelemenizi öneririm.

Not: Bu içerik, veritabanı yönetimi konusunda teknik bir rehber niteliğindedir. Uygulama öncesi mutlaka veritabanı yedeği alınız.

Bu yazıya tepkinizi paylaşın:
Deniz Arslan

On yıldır dijital içerik üretimi ve editörlük alanında çalışıyorum. Karmaşık süreçleri herkesin anlayabileceği basit ve adım adım rehberlere dönüştürme konusunda uzmanım.

Yorumlar (17)

17
okuyucu bu yazı hakkında yorum yaptı. Siz de deneyiminizi paylaşarak diğer okuyuculara yardımcı olabilirsiniz.
Caner Yılmaz
Caner Yılmaz 30 Temmuz 2026

Eline sağlık hocam, trigger konusunu hep karmaşık sanıyordum ama stok örneğiyle çok net anlaşılmış. Teşekkürler.

Deniz Arslan
Deniz Arslan 01 Ağustos 2026

Çok teşekkürler Caner, karmaşık görünse de mantığı kavrayınca çok keyifli oluyor. Başarılar!

Selin Baş
Selin Baş 02 Ağustos 2026

Ya ben bu kodu kopyalayıp SQL Serverda çalıştırdım ama hata alıyom, nerede yanlış yapıyor olabilirim acaba?

Kerem Tekin
Kerem Tekin 03 Ağustos 2026

Selin, 'GO' komutunu ekledin mi scriptin sonuna? Bazen o yüzden hata verebiliyor.

Mertcan G.
Mertcan G. 02 Ağustos 2026

SQL performansını düşürdüğü için trigger kullanmaktan korkuyorum aslında. Bu konuda bir tavsiyen var mı?

Deniz Arslan
Deniz Arslan 04 Ağustos 2026

Haklısın Mertcan, çok yoğun tablolarda dikkatli olmak lazım. Mümkünse iş mantığını uygulama katmanına çekmek daha sağlıklı ama küçük otomasyonlar için hala çok kullanışlı.

Zeynep Öz
Zeynep Öz 04 Ağustos 2026

Harika bir yazı olmuş, projelerimde hep manuel yapıyordum bu işlemleri, artık trigger ile daha temiz kod yazabilirim.

Burak Demir
Burak Demir 05 Ağustos 2026

trigger yazarken hata yakalama (try-catch) blokları hakkında da bi yazı yazarmısın? çok makbule geçer.

Deniz Arslan
Deniz Arslan 06 Ağustos 2026

Harika fikir Burak, bir sonraki yazımda mutlaka değineceğim.

Emre K.
Emre K. 05 Ağustos 2026

Anlatım gayet akıcı olmuş, emeğine sağlık. SQL öğrenenler için çok faydalı bir kaynak.

Derya Şahin
Derya Şahin 06 Ağustos 2026

Stok takibi için trigger yerine procedure kullanmak daha mı mantıklı? Arasındaki farkı tam çözemedim.

Cemil Uzun
Cemil Uzun 06 Ağustos 2026

Derya, procedure'ü sen çağırırsın ama trigger işlem anında kendi otomatik çalışır. Otomasyon için trigger daha iyidir.

Hakan Vural
Hakan Vural 06 Ağustos 2026

Kod bloklarını biraz daha detaylı açıklasaydın daha iyi olurdu sanki, yeni başlayanlar zorlanabilir.

Deniz Arslan
Deniz Arslan 07 Ağustos 2026

Geri bildirimin için teşekkürler Hakan, bir sonraki yazıda adımları daha küçük parçalara böleceğim.

Ayşegül T.
Ayşegül T. 06 Ağustos 2026

Sonunda şu trigger mantığını anladım ya, kaç gündür videolarla uğraşıyordum senin yazı tek seferde öğretti.

Oğuzhan S.
Oğuzhan S. 07 Ağustos 2026

Bu yöntemle loglama yapmak da çok kolaylaşıyor, onu da denedim bugün, eline sağlık gerçekten.

Deniz Arslan
Deniz Arslan 07 Ağustos 2026

Kesinlikle Oğuzhan, loglama için trigger vazgeçilmez bir yöntem. Denemene sevindim!

Yorum Yaz