Daha önce yazdığım SQL Server için gelişmiş log tutma yönetiminin MySQL versiyonu ile trigger işlemlerini detaylı bir şekilde ele alalım.

Yeni bir makale ile karşınızdayız. Önceden de belirttiğim üzere SQL Server'da Trigger (Tetikleme) ve Gelişmiş Log (Kayıt) Tutma Yöntemi adlı yazıya istinaden aynı yapının MySQL versiyonu ile ilgili talep geldi. Bunun üzerine kısa bir çalışma hazırlayarak bu konuyu MySQL içinde açığa kavuşturmuş olduk.
Konuya küçük bir giriş yaptıktan sonra kodlama kısmına başlayalım.
Basit düzeyde yapılmış bir öğrenci okul not sistemi üzerinden işleyişi anlatacağım. Öncelikle olarak tablolarımızı oluşturalım.

tblDersler Tablosu
CREATE TABLE tblDersler
(
ders_ID INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
ders_adi VARCHAR(255),
yil INT,
birinci_sinav_notu INT,
ikinci_sinav_notu INT
)


tblDersler Tablosu Görünümü




Tablomuzu oluşturduk. Sonrasında log tutacağımız tabloyu da benzer sütunlarla oluşturacağız. Tabi bu noktada birkaç farklılık olacak, tablo üzerinde insert-update-delete vs.. gibi işlemler yapılırken oturum açan kullanıcının bilgilerini de kayıt altına alalım ki istatistiksel olarak da elimizde hatırı sayılır kayıt olmuş olur.

Dersler Log Tablosu
CREATE TABLE tblDersler_Log
(
ders_ID INT,
ders_adi VARCHAR(255),
yil INT,
birinci_sinav_notu INT,
ikinci_sinav_notu INT,
log_ID INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
log_islem VARCHAR(30),
log_tarih TIMESTAMP NOT NULL DEFAULT NOW(),
log_olusturan VARCHAR(100),
log_ip VARCHAR(20)
)


tblDersler_Log Tablosu



Insert İşlemini Loglayalım

tblDersler tablosuna bir kayıt (insert) işlemi gerçekleştirelim. Insert işlemi öncesinde bu kaydın kopyasından tblDersler_Log tablosuna da ekleyelim.

tblDersler Tablosuna Insert Öncesi Trigger Yazalım
CREATE TRIGGER trgDersler_Before_Insert BEFORE INSERT ON tblDersler
FOR EACH ROW
BEGIN
DECLARE ip VARCHAR(20);
SELECT SUBSTRING_INDEX(host,':',1) INTO ip FROM information_schema.processlist WHERE ID=connection_id();
INSERT INTO
tblDersler_Log
(ders_ID, ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu, log_islem, log_tarih, log_olusturan, log_ip)
VALUES
(NEW.ders_ID, NEW.ders_adi, NEW.yil, NEW.birinci_sinav_notu, NEW.ikinci_sinav_notu, 'Insert Öncesi', NOW(), CURRENT_USER(), ip);
END


Oluşan Trigger'ı görsel olarak paylaşalım.

trgDersler_Before_Insert Trigger'ı



tblDersler tablosuna bir kayıt (insert) işlemi gerçekleştirelim. Insert işlemi sonrasında bu kaydın kopyasından tblDersler_Log tablosuna da ekleyelim.

tblDersler Tablosuna Insert Sonrası Trigger Yazalım
CREATE TRIGGER trgDersler_After_Insert AFTER INSERT ON tblDersler
FOR EACH ROW
BEGIN
DECLARE ip VARCHAR(20);
SELECT SUBSTRING_INDEX(host,':',1) INTO ip FROM information_schema.processlist WHERE ID=connection_id();
INSERT INTO
tblDersler_Log
(ders_ID, ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu, log_islem, log_tarih, log_olusturan, log_ip)
VALUES
(NEW.ders_ID, NEW.ders_adi, NEW.yil, NEW.birinci_sinav_notu, NEW.ikinci_sinav_notu, 'Insert Sonrası', NOW(), CURRENT_USER(), ip);
END


Oluşan Trigger'ı görsel olarak paylaşalım.

trgDersler_After_Insert Trigger'ı



Oluşan bu Trigger'ı test etmek için tblDersler tablosuna birkaç veri girelim.

tblDersler Tablosu Insert
INSERT INTO tblDersler
(ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu)
VALUES
('Matematik', 2002, 54, 71)

INSERT INTO tblDersler
(ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu)
VALUES
('Türkçe', 2002, 66, 57)

INSERT INTO tblDersler
(ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu)
VALUES
('İngilizce', 2002, 81, 87)


tblDersler Tablosuna Girilen Değerler



Insert Sonrası tblDersler_Log Tablo Kayıtları



Update İşlemini Loglayalım

Bu işlem için şöyle örnek verelim. Girilen bir kaydın birinci_sinav_notu değerini birkaç kez değiştirelim. Değiştirdiğimiz her kaydı ayrı ayrı kayıt olarak tblDersler_Log tablosuna işleyelim.
tblDersler Tablosunda Update Öncesi Loglama Yapalım
CREATE TRIGGER trgDersler_Before_Update BEFORE UPDATE ON tblDersler
FOR EACH ROW
BEGIN
DECLARE ip VARCHAR(20);
SELECT SUBSTRING_INDEX(host,':',1) INTO ip FROM information_schema.processlist WHERE ID=connection_id();
INSERT INTO
tblDersler_Log
(ders_ID, ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu, log_islem, log_tarih, log_olusturan, log_ip)
VALUES
(OLD.ders_ID, OLD.ders_adi, OLD.yil, OLD.birinci_sinav_notu, OLD.ikinci_sinav_notu, 'Update Öncesi', NOW(), CURRENT_USER(), ip);
END


Oluşan Trigger'ı görsel olarak paylaşalım.

trgDersler_Before_Update Trigger'ı



tblDersler Tablosunda Update Sonrası Loglama Yapalım
CREATE TRIGGER trgDersler_After_Update AFTER UPDATE ON tblDersler
FOR EACH ROW
BEGIN
DECLARE ip VARCHAR(20);
SELECT SUBSTRING_INDEX(host,':',1) INTO ip FROM information_schema.processlist WHERE ID=connection_id();
INSERT INTO
tblDersler_Log
(ders_ID, ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu, log_islem, log_tarih, log_olusturan, log_ip)
VALUES
(NEW.ders_ID, NEW.ders_adi, NEW.yil, NEW.birinci_sinav_notu, NEW.ikinci_sinav_notu, 'Update Sonrası', NOW(), CURRENT_USER(), ip);
END


Oluşan Trigger'ı görsel olarak paylaşalım.

trgDersler_After_Update Trigger'ı



Oluşan trigger'ı test etmek için şöyle yapalım. 2002 yılındaki İngilizce dersinin 81 olan birinci_sinav_notu değerini ilk olarak 44 yapalım. Sonrasında ise 91 olarak güncelleyelim.

tblDersler_Log Tablosu Update Sonrası Kayıtlar



Delete İşlemini Loglayalım

Bu işlemi ise yanlışlıkla silinen verileri kayıt altına almak için tblDersler_Log tablosuna kayıt edelim.

tblDersler Tablosunda Delete Öncesi Loglama Yapalım
CREATE TRIGGER trgDersler_Before_Delete BEFORE DELETE ON tblDersler
FOR EACH ROW
BEGIN
DECLARE ip VARCHAR(20);
SELECT SUBSTRING_INDEX(host,':',1) INTO ip FROM information_schema.processlist WHERE ID=connection_id();
INSERT INTO
tblDersler_Log
(ders_ID, ders_adi, yil, birinci_sinav_notu, ikinci_sinav_notu, log_islem, log_tarih, log_olusturan, log_ip)
VALUES
(OLD.ders_ID, OLD.ders_adi, OLD.yil, OLD.birinci_sinav_notu, OLD.ikinci_sinav_notu, 'Delete Öncesi', NOW(), CURRENT_USER(), ip);
END


Oluşan Trigger'ı görsel olarak paylaşalım.

trgDersler_Before_Delete Trigger'ı



Oluşan bu Trigger'ı test etmek için tblDersler tablosunda ders_ID = 2 olan kaydı silelim.

tblDersler Tablosu Delete
DELETE FROM tblDersler WHERE ders_ID = 2

tblDersler Tablosu Delete Sonrası Kayıtlar



tblDersler_Log Tablosu Delete Sonrası Kayıtlar



Görüldüğü gibi yapılan bütün işlemleri basit düzeyde kayıt altına almış olduk.

Bol loglamalı günler :)

Kaynak: https://www.ontedi.com/sql/mysqlde-trigger-tetikleme-ve-gelismis-log-kayit-tutma-yontemi