Ünite 4: Kısıtlayıcı ve Tetikleyiciler

Giriş

Verilerin sorgulanması veya değiştirilmesi kullanıcı veya arayüz tarafından oluşturulacak sorgularla yapılan veritabanları pasif veritabanları olarak isimlendirilmektedir. Ancak bazı uygulamalarda sorgulamaya gerek kalmadan veritabanının otomatik olarak tepki göstermesi gerekliliği vardır. Eğer bir veritabanının kendisi otomatik olarak tepki üretebiliyor ise bu tür veritabanı aktif veritabanı olarak isimlendirilmektedir. Aktif veritabanı sistemlerinde, oluşturulacak bazı kurallar ile otomatik tepki vermesi sayesinde daha güçlü uygulamalar yapılabilmesi sağlanmıştır.

Veritabanı ister aktif ister pasif olsun, en genel anlamda ilişkisel bir veritabanı birbiriyle ilişkili tablolardan, tablolar da satır ve sütunlardan oluşmaktadır. Bu tablolardaki kayıtların ve verilerin birbiriyle tutarlı olması gerekmektedir ki bu tutarlılık veri bütünlüğü olarak ifade edilmektedir. Veri bütünlüğü, bir tabloda verilere UPDATE, DELETE veya INSERT gibi işlemler yapılırken diğer tablo ya da tablolardaki verilerin birbirleriyle uyum içinde olmasının sağlanmasıdır. Veri bütünlüğü bu uyumluluk ile veri tutarlılığının garanti altına alınması demektir. Bu bütünlüğü sağlamak için Tanımlanabilir Veri Bütünlüğü (Declarative Data Integrity) ve Prosedürel Veri Bütünlüğü (Procedural Data Integrity) olmak üzere iki farklı şekilde yapılabilmektedir. Bunlardan ilki, kullanımı çok basit ve nesnelerin kendi özelliklerini kullanarak sağlanabilen veri bütünlüğüdür. Ancak tanımlanabilir veri bütünlüğünde çok fazla müdahale edilememesi ve programlama imkânının sağlanamaması gibi dezavantajlarından dolayı daha üst düzey programlamayla müdahale edilerek üst düzey veri bütünlüğü sağlanması gerekir ki bu da ikinci tip olarak karşımıza çıkar ve prosedürel veri bütünlüğü olarak isimlendirilir.

Aktif Veritabanları ve Veri Bütünlüğü

Veritabanı içinden veya dışından gelen olaylara oluşturulacak kurallar sayesinde otomatik olarak tepki üreten veritabanına aktif veritabanı denir. Aktif veritabanı sistemlerinde, oluşturulacak bazı kurallar ile tepki vermesi sayesinde daha güçlü uygulamalar yapılabilmesi sağlanmıştır. Genel olarak bu tür aktif veritabanı sistemlerinde, otomatik olarak gerçeklenmesi istenen eylem veya tepkiler bir koşula bağlanır. Eğer koşul gerçeklenirse sorgulamaya gerek kalmadan veritabanı sistemi kendisine tanımlanan eylem veya tepkiyi otomatik olarak gerçekler. Bu tür eylem veya tepkilere veritabanındaki kayıtların bütünlülüğünün sağlanması, verilere erişim ve değişimlerin incelenmesi, türetilmiş verilerin korunması, sürüm geçmişlerinin izlenmesi, sistemde ortaya çıkabilecek ani değişikliklere kolayca uyum sağlayabilmek en basit örneklerdir. Oluşturulabilecek kurallar sayesinde, veritabanı sistemleri geniş ve verimli bilgi tabanı ve uzman sistemler oluşturmak için uygun bir platform olur.

Veritabanı tablolarındaki sütunlara girilen verilerin hem tip hem de tanım kümesi olarak doğru ve tutarlı olması gerekir. Bu kapsamda verinin doğru ve tutarlı bir şekilde işlenmesi veri bütünlüğü olarak ifade edilmektedir. Verilerin doğruluğunu ve tutarlığını sağlamak için bazı kısıtlamalara ihtiyaç duyulmaktadır. Veritabanındaki veri bütünlüğü açısından bir tablodaki sütunlara doğru ve tutarlı verilerin girilmesinin sağlanması tek başına yeterli olmamaktadır. Örneğin, veritabanındaki bir tabloda veriler silindiğinde, güncellendiğinde veya ekleme yapıldığında yapılan düzenlemelere ve değişikliğe göre diğer tabloların da düzenlenmesi ve değiştirilmesi gerekebilir. Dolayısıyla veritabanı bütünlüğü denildiği zaman sadece girilen kayıtların doğru ve tutarlı olarak anlaşılmaması, bütün tablolardaki kayıtların ve tabloların birbiriyle tutarlı olduğunun anlaşılması gerekmektedir. Kısacası veri bütünlüğü, bir tabloda veri güncelleme, silme veya ekleme gibi işlemler yapılırken veri tutarlılığının kaybolmamasının garanti altına alınması demektir. Diğer bir ifadeyle bir tablodaki yapılan herhangi bir işlemin diğer tablo ya da tablolardaki verilerle uyum içinde olmasının sağlanmasıdır.

Veri bütünlüğünü sağlama yöntemleri temel olarak iki tipe ayrılmaktadır. Bunlardan ilki kullanımı çok basit olan ve tanımlanabilir veri bütünlüğü olarak isimlendirilen tanımlanan nesnelerin kendi özellikleri sayesinde sağlanabilen veri bütünlüğüdür. Ancak bu veri bütünlüğünde, çok fazla müdahale edilememesi ve programlama imkânının sağlanamaması dezavantajları olarak sayılabilir. Bazı durumlarda ise daha üst düzey programlamayla müdahale edilerek daha üst düzey veri bütünlüğü sağlanması gerekir ki bu da ikinci tip olarak karşımıza çıkar ve prosedürel (Programsal) veri bütünlüğü olarak isimlendirilir. Programsal veri bütünlüğü sağlamaya çalışırken kötü yazılacak program ile veritabanına ek yük getirebilir.

Kısıtlayıcılar

Veritabanında bütünlüğü sağlamak için veri üzerindeki oluşturulmuş mantıksal sınırlamalara kısıt adı verilir. Kısıtların kullanılmasının en temel sebebi veritabanına hatalı giriş yapılmasını engellemektir. Kısıtlar, veritabanı bütünlüğü sağlama tekniklerinden, tanımlanabilir veri bütünlüğü teknikleri arasında yer almaktadır.

Tanımlanabilir veri bütünlüğü esasları aşağıdaki şekilde sıralanabilir:

  • Satır Bütünlüğü: Tabloya girilen kayıtlardan her bir kaydın diğer kayıtlardan farklı bir değer olmasını sağlar.
  • Sütun Bütünlüğü: Tablodaki herhangi bir sütunun hangi gruptan verileri alabileceğini veya NULL bir değer alıp alamayacağını sağlar.
  • Referanssal Bütünlük: Referanssal bütünlük kısıtları bir kolondaki bilginin diğer bir kolon ile eşleşmesi zorunluluğunu sağlayarak bütünlüğü korur. Eşleşen kolonlar farklı iki tablonun kolonları olabileceği gibi aynı tablonun kolonları da olabilir.

Birincil anahtar kısıtlayıcısı (primary key constraint), bir tablodaki bir satıra girilen verilerden her bir satırı diğer satırlardan ayıran tanımlayıcı bir değer olmasını sağlar. Birinci kısıtlayıcı ile bir satıra daha önce girilmemiş değerler girilmesi sağlanır. Bu sayede her satırın diğer satırlardan farklı olmasını gerçekleştirir ve her satırın tekilliğini sağlar. Bir sütuna birincil anahtar kısıtlayıcısı tanımlanır ise o sütundaki tüm satırlara bir değer girilmesini zorlar yani NULL kalamaz. Her tabloda en fazla bir adet birincil anahtar kısıtlayıcısı bulunabilir. Birincil anahtar alana girilen veriler tekil olmak zorundadır.

Birincil anahtar kısıtlayıcı yeni bir tablo oluştururken aşağıdaki şekilde tanımlanır:

CREATE TABLE Tablo Adı (
Sütun_Id INT NOT NULL,
Sütun_Adi1 VARCHAR (150) NOT NULL
CONSTRAINT Kısıtlayıcı_Adı PRIMARY KEY (Sütun_Adı)
)

Oluşturulmuş bir tabloda aşağıdaki şekilde tanımlanır:
ALTER TABLE Tablo Adı
ADD CONSTRAINT Kısıtlayıcı_Adı PRIMARY KEY (Sütun_Adı)
Tekil alan kısıtlayıcısı (unique constraint) ile istenilen sütundaki verilerin tekil ( her değerden sadece bir tane) olması sağlanır. Birincil anahtar kısıtlayıcısının aksine tablodaki birden fazla sütuna tekil kısıtlayıcı tanımlanabilir ve sütundaki değer NULL olabilir. Eğer sütunu girilen değer NULL değil ise tekil alan kısıtlayıcısı tanımlanan sütuna mutlaka farklı değerler girilmesini sağlar.

Tekil alan kısıtlayıcı yeni bir tablo oluştururken aşağıdaki şekilde tanımlanır:

CREATE TABLE Bolumler (
Bolum_No INT not NULL,
Bolum_Adi VARCHAR (150) not NULL
CONSTRAINT Tak_Bolumler_Bolum_No UNIQUE (Bolum_No)
CONSTRAINT Tak_Bolumler_Bolum_Adi UNIQUE (Bolum_Adi)
)

Oluşturulmuş bir tabloda aşağıdaki şekilde tanımlanır:

ALTER TABLE Bolumler
ADD CONSTRAINT Tak_Bolumler_Bolum_No UNIQUE (Bolum_No)
ADD CONSTRAINT Tak_Bolumler_Bolum_Adi UNIQUE (Bolum_Adi)

Kontrol kısıtlayıcısı (check constraint) tablodaki herhangi bir sütunun hangi gruptan verileri alabileceğini ve girilebilecek verileri bir koşul ile kısıtlayarak istenilen verilerin girilmesini sağlayan bütünlüktür. Bununla beraber sütunun NULL değer alıp alamayacağının kontrolü de bu kısıtlayıcı ile sağlanabilir. Ayrıca iki farklı sütun değerini karşılaştırarak farklı sütunlardaki veri bütünlüğü de sağlanabilir. Aslında temel olarak Kurallar nesnesi ile aynı işleve sahiptir.

Kontrol kısıtlayıcısı yeni bir tablo oluştururken aşağıdaki şekilde tanımlanır:

CREATE TABLE Bolumler (
Bolum_Adi VARCHAR (150) not NULL,
Bolum_No INT not NULL,
CONSTRAINT KK_Bolumler_Bolum_No CHECK (Bolum_No>0)
)

Oluşturulmuş bir tabloda aşağıdaki şekilde tanımlanır:

ALTER TABLE Bolumler
ADD CONSTRAINT KK_Bolumler_Bolum_No CHECK (Bolum_No>0)

Yabancı anahtar kısıtlayıcısı (foreign key constraint), bir tablodaki bir sütundaki değerin diğer taboloardaki değerlerle denetlenmesini sağlayan kısıtlayıcıdır. Tablolar arasındaki veri bütünlüğünü sağladığı gibi ilişkili tabloları da gösterir. Bir tabloya yabancı anahtar kısıtlayıcısı tanımlandığı zaman referans edilen ve referans eden iki tablo arasında bir ilişki kurulması sağlanır. Böylece bir tablo için yabancı anahtar kısıtlayıcısı tanımlanmış ise bu tabloya girilecek her kaydın referans edilen tablodaki kayıtla eşleşmesi gerekir. Eğer yabancı anahtar kısıtlayıcı olan sütun NULL değerler alabiliyorsa bu durumda eşleşme aranmaz.

Yabancı anahtar kısıtlayıcı yeni bir tablo oluştururken aşağıdaki şekilde tanımlanır:

CREATE TABLE Urunler (
Urun_No int IDENTITY (1,1) NOT NULL,
Urun_Adi nvarchar (50) NULL,
Urun_Sayisi int NULL,
Urun_Fiyati decimal (18, 2) NULL,
Bolum_No int NULL,
CONSTRAINT Yak_Urunler_Bolum_No
FOREIGN KEY (Bolum_No) REFERENCES Bolumler (Bolum_No)
)

Oluşturulmuş bir tabloda aşağıdaki şekilde tanımlanır:

ALTER TABLE Urunler
ADD CONSTRAINT Yak_Bolumler_Bolum_No
FOREIGN KEY (Bolum_No)
REFERENCES Bolumler (Bolum_No)

Varsayılan kısıtlayıcısı (default constraint), ekleme işlemi için geçerli olan ve bir tabloya veri girişi esnasında verinin girildiği alan için alacağı varsayılan bir değerin tanımlanması için kullanılan kısıtlayıcıdır. Varsayılan kısıtlayıcılar için en pratik uygulama alanı işlemlerin gerçekleşme tarihlerini kaydetmek için sistem tarihini alan bir sütun tanımlamaktır.

Varsayılan kısıtlayıcısı yeni bir tablo oluştururken aşağıdaki şekilde tanımlanır:

CREATE TABLE Satislar(
Satis_No INT not NULL,
Urun_No INT NULL,
Calisan_TC_No nvarchar(11) NULL,
Fiyat decimal(18, 2) NULL,
Tarih date NULL,
Miktar INT CONSTRAINT VK_Miktar DEFAULT (1),
)

Oluşturulmuş bir tabloda aşağıdaki şekilde tanımlanır:

ALTER TABLE Satislar
ADD CONSTRAINT VK_Miktar DEFAULT (1)
FOR Miktar

Tetikleyiciler

Saklı yordamların özel bir çeşidi olan tetikleyiciler kullanılarak SQL Server üzerinde herhangi bir eylem gerçeklendiğinde başka bir eylemin gerçeklenmesi sağlanabilir. Yani yapılan bir eylem sonrası başka bir eylemin yapılması tetiklenebilinir. Tetikleyiler, genelde veritabanı bütünlüğünün sağlanması için kontrol mekanizmaları oluşturmak amacıyla kullanılırlar. Bununla beraber veritabanı bir eylem gerçekleştirdiği zaman aynı veya başka bir tabloya kayıt ekleme, silme veya güncelleme ile beraber rapor almak gibi başka eylemleri gerçeklemek için kullanılabilir. Özetle tetikleyiciler, veritabanı bir eylem gerçeklediğinde otomatik olarak başka eylem / veya eylemler gerçeklemesi amacıyla kullanılan özel saklı yordamlardır.

MS SQL Server’da iki farklı tetikleyici türü vardır. Bunlar ardı sıra ve yerine tetikleyicileridir. Ardı sıra tetikleyiciler, veritabanında bir eylem gerçeklendiği zaman başka bir eylem veya eylemlerin gerçeklenmesi istediği zaman kullanılan tetikleyicilere ardı sıra tetikleyicileri denilmektedir. Veritabanındaki temel işlemler (ekleme, silme ve güncelleme) için ardı sıra tetikleyicileri tanımlanabilir. Yerine tetikleyiciler, ardı sıra tetikleyicilerinin aksine tetikleyiciyi çağıran eylem gerçekleşirken devreye giren ve kendi içinde tanımlanan komutları icra etmeye başlayan tetikleyicilerdir. Yani, tetikleyici çağıran eylem yerine geçerek tanımlanan eylemleri gerçekleştirerek çoğunlukla kontrol amaçlı kullanılırlar.

Bir tetikleyicinin genel yapısı aşağıdaki gibidir:

CREATE TRIGGER tetikleyici_adi ON tablo_adi
FOR veya AFTER veya INSTEAD OF (INSERT veya UPDATE veya DELETE)
AS
(SQL ifadeleri…)

Bir tablo üzerinde yeni kayıt veya kayıtlar girildikten sonra otomatik olarak bir eylem veya eylemler yapılması istenildiği zaman INSERT tetikleyicisi kullanılır. INSERT tetikleyici devreye girdikten sonra yeni eklenen kayıtların bir kopyasının tutulduğu sahte bir tablo oluşturulur. Bu sahte tablo, tetikleyici sonlana kadar saklanan bu tablo asıl tablonun yapısal bir kopyasıdır. SQL Server, satır bazında tetikleyici desteği sağlamamaktadır ve dolayısıyla eğer bir tabloya birden fazla kayıt girildiyse tetikleyici her kayıt için ayrı ayrı devreye girmeyip tek seferde bütün eklenen kayıtlar için yapılması istenen işlemi gerçekleştirir.

Tablodan bir kayıt silindiğinde otomatik olarak yapılması istenen işlemler için kullanılan bu tetikleyicide silinen kayıtlar DELETED sahte tablosuna kaydedilir. DELETED sahte tablosunun INSERTED sahte tablosundan farkı, asıl tablodan silinen kayıt artık DELETED sahte tablosunda yer almaktadır. Böylece silme işleminden vazgeçilmesi durumunda kayıt kaybedilmemiş olur.

Tablo üzerindeki kayıt ya da kayıtlarda güncelleme olduğunda devreye girer. INSERT ve DELETE tetikleyicilerden farklı olarak UPDATE tetikleyici devreye girdiğinde eklenen sahte tablosu asıl tablodaki kayıtlardan, düzenlenmiş kayıtların kopyasını; silinen sahte tablosu ise kayıtların düzenleme işleminden önceki hâllerini tutar.

Kısıtlayıcılar ve Tetikleyicilerin Karşılaştırılması

Tetikleyiciler ile Kısıtlayıcıları karşılaştırmak için aşağıdaki gibi bir senaryo düşünelim. Bir tabloya Ad ve Soyadı bilgisinin aynı anda beraber güncelleme yapılması istenmektedir. Eğer sadece Soyadı bilgisi güncellenmek istenirse ve Ad bilgisi Null ise güncelleme işleminin gerçekleştirilmemesi gerekmektedir. Bu işlemin tetikleyici ile yazımı aşağıdaki kodda verilmiştir.

Create Trigger Trig_Ad_Soyad On calisanlar
After INSERT
As
DECLARE @strAd VARCHAR(50)
SELECT @strAd = (SELECT Adi FROM inserted)
IF UPDATE (Soyad) AND @strAd IS NULL
BEGIN
ROLLBACK TRANSACTION
RAISERROR (‘Ad ve Soyadı bilgisi girilmek zorundadır’, 11, 1)
END

Aslında örnekte tetikleyici ile yapılmak istenen eylemin, kısıtlar kullanılarak da yapılması mümkündür. Çünkü Ad ve Cinsiyet bilgisi aynı tabloda bulunmaktadır. Eğer farklı tablolar kullanarak bir eylem gerçekleştirilmek istenirse tetikleyicilerin kullanılması zorunlu hâle gelmektedir. Kısıtlayıcılar başka tablo veya satırlara erişemezler. Ama tetikleyicilerin diğer tablo ve satırlara erişim hakkı vardır. Böyle durumlarda tetikleyiciler kısıtlayıcılara karşı üstündür.