SQL etiketine sahip kayıtlar gösteriliyor.
SQL etiketine sahip kayıtlar gösteriliyor.

SQL'de CHARINDEX Fonksiyonu Kullanımı

Transact-SQL dilinde kullanılan önemli karakter fonksiyonlarından biriside CHARINDEX'dir. Bu fonksiyon bir karakter dize içinde belirtilen bir ifadenin (karakterin) başlangıç konumunu döndürür. Örneğin e-mailleri tutan bir alanınız mevcut, burada "@" işareti öncesi ve sonrasını belirlemede veya ',' ile ayrılmış bir karakter dizesinde virgül öncesini ve sonrasını belirlemede kullanabilirsiniz. Kısaca bir karakter kümesinin içerisinde geçen bir karakterin, bu karakter kümesinde kaçıncı karakter olduğunu bulmak için ve bir string ifade içinde başka bir string ifade aramak için kullanırız.

Kullanımı : CHARINDEX ( ifade1, ifade2[ , başlangıç konumu] )  
İfade1: Aranacak karakterleri belirtir.  
İfade2: İfade1'deki karakterlerin aranacağı karakterleri belirtir. 
Başlangıç Konumu: Aramanın başlanacağı konumu belirtir.

Döndürdüğü Tür: Int 
 
İfadelerden birisi NULL ise CHARINDEX fonksiyonu NULL değerini döndürür. İfade1, İfade2 içinde bulunamazda 0 değeri döner.

CHARINDEX fonksiyonu 2 parametre almaktadır. 1.parametredeki değerin 2.parametre olarak verilmiş değerde olup olmadığını belirtir. Kullanımı oldukça basittir. 

Örnek Sorgu 1: 
DECLARE @ornek1 varchar(255)
SET @ornek1= 'Cogito ergo Sum: Düşünüyorum, o halde varım. René Descartes'
SELECT CHARINDEX('ergo', @ornek1)
SELECT CHARINDEX(',', @ornek1) 

Örnek Sorgu 2: 
SELECT Adi, CHARINDEX('A',Adi)
AS "A Harfinin Konumu",
CHARINDEX ('a',Adi) AS "a Harfinin Konumu"
FROM dbo.Personeller

Örnek Sorgumuzda a ve A değerleri aynıdır. Aranan değerin ilk bulunduğu konumunun yeri döner. Diğer sonraki konumlar dikkate alınmaz. Yani tek karakter için büyük küçük harf ayrımı yoktur.

Örnek Sorgu 3: 
SELECT CHARINDEX ('E','Ne kadar bilirsen bil, söylediklerin karşındakinin anlayabileceği kadardır. Mevlana')
SELECT CHARINDEX ('L','Zeki adamlar söyleyecek bir şeyleri olduğu için konuşurlar. Aptallar, konuşmaları gerektiği için. Platon')
SELECT CHARINDEX ('KİMSE','Bir kimsenin düşüncesini açıklayamaması köleliktir. Euripides')
SELECT CHARINDEX ('DİY','Dünyanın ahlaksız diye adlandırdığı kitaplar dünyaya kendi utancını gösterenlerdir. Oscar Wilde') 

SQL'de Server Adını Değiştirme

SQL Server kurulu bilgisayarımızın veya sunucumuzun bilgisayar adı değiştiğinde SQL Server adı değişmemekte ve bununla birlikte bilgisayar adının değişmesin sorunlara neden olur. SQL server adını aşağıdaki Stored Procedure leri kullanarak değiştirebiliriz:

SQL Server Management Studio da Yeni bir Query ekranı açalım:
sp_dropserver 'EskiSunucuAdimiz'
sp_addserver  'YeniSunucuAdimiz', 'local'

Execute işlemini yaparak değişikliği sağlıyoruz. Eğer SQL Server da default instance dan başka instance lar mevcut ise:
sp_dropserver <EskiSunucuAdimizinstancename>
sp_addserver  <YeniSunucuAdimizinstancename>, local

Son olarak MSSQL servisini restart edip yapmış olduğumuz değişikliği aşağıdaki sorguya sunucu adımızı girerek kontrol edebiliriz.
SELECT @@SERVERNAME as "SunucuAdimiz"

SQL'de Detach/Attach İşlemleri

Bir MDF ve LDF dosyasından oluşan veritabanı, VTYS sistemine bağlı iken sistem dosyaların taşınmasına izin vermez Bu durumda dosyalar önce sistemden "Detach" ile ayrılmalı, daha sonra tekrar istenen başka bir sunucuda "Attach" edilmelidir.

Detach İşlemi


Detach yapılmak istenen veritabanına sağ tıklanır ve Tasks / Detach ile Detach Database ekranı açılır.

Veritabanı sistemden ayrılırken, aktif bağlantılar otomatik kapatılsın mı?  (Drop Connections) Eğer bu seçenek seçilmezse ve aktif bağlantılar varsa, veritabanı ayrılması gerçekleşmeyecektir.

Attach İşlemi
Sistemden ayrılan veritabanına ait MDF ve LDF dosyasının yeri gösterilecek, istenen herhangi bir SQL Server sunucusuna tanıtılabilir.  


Attach yapılmak istenen veritabanı dosyası için Databases sağ tıklanır ve Attach ile Attach Databases ekranı açılır. Açılan ekranda Add butonu ile Attach edilmek istenen VT eklenir OK butonuna tıklanır. OK tuşuna tıkladıktan sonra Database Server'a eklenmiş oldu Server da bunu görmek için Object Explorer penceresinden Refresh işlemi yapılmalıdır.

SQL Server 2012 "Edit Top 200 Rows" Satır Sayısını Değiştirme

SQL Server'da tablodaki verileri görmek ve editlemek istediğimizde "Edit Top 200 Rows"u açarız, fakat tablolarımızdaki verilen kimi zaman 200'den fazla olabiliyor. 


"Edit Top 200 Rows" sınırını arttırmak  için SQL Server'da neler yapabiliriz?

"Edit Top 200 Rows" seçeneğinde varsayılan değer 200 olan satır sayısını değiştirelim ve bütün tablolara sağ tıkladığımızda "Edit Top 2000 Rows" yapalım.  Menü araç çubuğundan Tools-Options'a giriyoruz.


Açılacak olan Options penceresinde "SQL Server Object Explorer"a tıklıyoruz.


Options penceresinde sağ kısımda "Value for Edit Top <n> Rows command" satırındaki 200'ü 2000 olarak değiştiriyoruz. Artık SQL Server'da hangi tabloya sağ tıklarsak "Edit Top 2000 Rows" olarak değiştiğini görebiliriz. 


Not: Options penceresinde "Value for Edit Top <n> Rows command" altında bulunan "Value for Select Top <n> Rows command" seçeneğinden de "Select Top 1000 Rows" değişikliğinide yapabiliriz.

Eğerki bu değişikliği SQL Server için varsayılan bir değer değilde belirli bir tabloda geçici olarak yapmak istiyorsak Tablomuzun üzerine sağ tıklayıp "Edit Top 200 Rows" açıyoruz. Tablomuz edit modunda açıldıktan sonra toolbardan "Show SQL Pane" butonuna tıklıyoruz.

Query ekranına tabloyu 200 satır olarak edit modda açan SQL kodu gelecek. Bu kodda 200 yazan yeri değiştirerek toolbardan "Execute SQL" butonuna tıklıyoruz.

SQL'de Hata Fırlatmak RAISERROR Kullanımı

Bazı durumlarda SQL serverın hata fırlatmasını beklemeden kendimiz sorgunun hata fırlatıp bitmesini isteriz. Örneğin TRY CATCH ile yakalanamayan hataları kullanıcıya bildirebilmek için TRY CATCH yapısı içinde RAISERROR fonksiyonunu kullanabiliriz. Veya yazdığımız SP yada Trigger hata vermeden bizim kendi kontrollerimiz ile hata fırlatmasını sağlayabiliriz. Ayrıca bu fonksiyon ile kullanıcıya istemiş olduğumuz mesajı verme hakkına da sahibiz. İstediğimiz durum SQL Hatası olmayıp bizim koyduğumuz kontrol neticesinde bir mantık hatası olabilir.

NOT : Örnek sorgulamada Northwind Database'i kullanacağım. bk: Nortwind Database Kurulumu

Genel Yapısı:
RAISERROR('Hata Mesajımız',ERROR_SEVERITY, ERROR_STATE) [WITH LOG]
Örnek: Northwind veritabanımızda sipariş numarası girilerek kayıtların listelenmesi ile ilgili bir sorguda RAISERROR fonksiyonunu kullanalım. Öncelikle hata oluşması durumunda verilecek mesajı sisteme tanımlayalım. Bunun için;
sp_addmessage @msgnum=90001,
@severity=11,
@msgtext='GİRİLEN SİPARİŞ NUMARASI 0 DAN KÜÇÜK VE 11100 DEN BUYUK OLAMAZ',
@with_log='true'

ERROR_SEVERITY değeri olarak 11 vermemizin nedeni severity değer aralığında 11-16 arası "Kullanıcıların düzeltebileceği hatalar" anlamına gelmesidir.Sisteme  yeni mesaj eklemek için "sp_addmessage" sistem saklı prosedürü kullanılır. Mesaj numarasını 90001 olarak vermemin özel bir nedeni yok sadece bilinmesi gereken nokta SQL Server mesaj numaralarının ilk 50000'i kendisine ayırmıştır ve eklenecek mesaj numarasının 50000'den büyük olması yeterlidir. "msgtext" ise hata durumunda verilecek mesajımızdır. Kullanıcı tanımlı mesajları silmek için "sp_dropmessages" sistem saklı prosedürü kullanılır. Gelelim örneğimize;

90001 numaralı hata mesajını sisteme ekledik. Şimdi verilen sipariş numarasına göre Northwind veritabanımızda Order Details tablosu içerisinde arayarak kayıtların listelenip listelenmeyeceğinin belirlendiği bir prosedür oluşturalım.
CREATE PROCEDURE SIPARIS_URUN_LISTE
(
@ID INT=NULL
)
AS
IF @ID IS NULL
BEGIN
RAISERROR ('SIPARIS NUMARASI GIRMELISINIZ',10,1)
RETURN 0
END
IF @ID<0 OR @ID>11100
BEGIN
RAISERROR (90001,10,1)
RETURN 0
END

SELECT * FROM [Order Details]
WHERE OrderID=@ID

Stored Procedure'müzde "ID" değişkenimizi int tipinde tanımladık ve NULL değerini atadık. Prosedürümüzün çalıştırılmasında değişkenimize herhangi bir değer atanmadıysa hata mesajı RAISERROR fonksiyonuyla bize döndürülecektir.

RAISERROR Kullanımı ile ilgili Detaylı bilgi için tıklayınız.

SQL'de TRY CATCH Kullanımı

Bu makalemde SQL Server Hata Yakalama Bloğu (TRY-CATCH) kullanımına değineceğim. 

TRY CATCH Yapısı
TRY CATCH yapısı TRY ve CATCH bloğundan oluşur. Eğer TRY bloğunda bir hata oluşursa kontrol CATCH bloğuna geçer. Bir hata oluşmamışsa CATCH blogu devreye girmez. Bir hata varsa CATCH blogunda hata yakalanır.  CATCH blogunun işletilmesi tamamlandıktan sonra akış bloktan sonraki kodlarla devam eder.

TRY CATCH kullanımında sadece TRY bloğunu tanımlayıp bırakamayız. Bir TRY bloğu tanımladıysak CATCH bloğunuda tanımlamak zorundayız.

Genel Yapısı:
BEGIN TRY
--SQL Kodlar (Hata olabilecek kod bloğu)
END TRY
BEGIN CATCH
--SQL Kodlar (Hata olduğunda hatanın yakalandığı kısım.)
END CATCH

MS SQL'de TRY CATCH fonksiyonunun çeşitli işlevsel özellikleri vardır. Bu özellikler CATCH bloğu içinde kendi değerlerini korurlar, CATCH bloğu dışında ise geriye NULL dönerler. 

ERROR_SEVERITY() Hata Dereceleri
  • 0 veya 10 : Kullanıcı veri girişinden kaynaklanan hata 
  • 11-16 arası: Kullanıcının düzeltebileceği bir hata 
  • 17 : Yetersiz kaynak hatası (Diskin dolu olması veya tablonun salt okunur olması vb.) 
  • 18 : Yazılımdan kaynaklanan hata 
  • 19 : Constraint'lere takılan bir hata 
  • 20-25 arası: Kritik hatalar
Örnek 1:
BEGIN TRY
DECLARE @Sayi int = 8/0
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER()    AS 'Hata Numarası',
ERROR_SEVERITY()  AS 'Hata Derecesi',
ERROR_STATE()     AS 'Hata Kod Değeri',
ERROR_PROCEDURE() AS 'Hata SP',
ERROR_LINE()      AS 'Hata Satır Numarası',
ERROR_MESSAGE()   AS 'Hata Mesajı'
END CATCH

 
Örneğimizde 8 sayısı 0'a bölünmeye çalışılıyor. 0'a bölme hatası alıyoruz ve CATCH bloğuna geçiyoruz. Fakat sorgu devam ediyor. Eğer TRY-CATCH kullanmasaydık sorgumuz hata verdiği anda sonlanacaktı.

NOT: TRY-CATCH sadece çalışma anındaki hataları yakalayabilir. SQL kodumuzdaki syntax hatalarını yakalayamaz.

Örnek 2:
BEGIN TRY
DROP TABLE TABLO5;
END TRY
BEGIN CATCH
PRINT 'Hata Oluştu'
PRINT ERROR_NUMBER();
PRINT ERROR_SEVERITY();
PRINT ERROR_STATE();
PRINT ERROR_LINE();
PRINT ERROR_MESSAGE();
END CATCH

Örneğimizde mevcut olmayan bir tabloyu drop etmek istedim ve dolayısıyla varolmadığı için bir hata oluştu. CATCH bloğuna PRINT ile "Hata Oluştu" mesajını ve TRY-CATCH fonksiyon özelliklerinide yine PRINT ile ekrana yazdırdık.

SQL'de Temporary (Geçici) ve Değişken (Variable) Tabloların Kullanımı

SQL'de oluşturulan geçici tablolar, kullanıcıya ait olan veritabanında tutulmazlar. SQL Server’da tempdb içinde tutulurlar. Bu tempdb sisteme ait bir veritabanıdır. tempdb geçici tabloları tuttuğu gibi aynı zamanda SQL Server üzerinde çalıştırılan sorgular sonucu arka planda tablosal işlemlerin yapıldığı ve verilerin bizim ekranımızda geçici olarak oluşturulduğu yapınında gerçekleşmesini sağlarlar. SQL'de Temporary tablo oluştururken iki seçeneğimiz bulunmakta. Bunlar kullanım şeklinize göre farklılık gösterebilir.
  • Geçici Tablolar (Temporary Tables)
  • Değişken Tablolar (Table Variables)
Geçici Tablolar (Temporary Tables)
Geçici tabloları oluşturmak için de tıpkı normal bir tabloyu oluşturmakta kullandığımız "CREATE TABLE" ifadesini kullanırız. Fakat oluşturulan tablonun gerçek bir tablo mu yoksa geçici bir tablo mu olduğunun ayırt edilmesi için; oluşturduğumuz tablonun sanal bir tablo olduğunu SQL'e "#" işaretini kullanarak bildiririz. CREATE TABLE ifadesinden sonra yazılan tablo isminin başına "#" işaretini eklediğimizde SQL bu tablonun geçici bir tablo olduğunu algılar ve oluşturulan tabloyu yalnızca ilgili oturum için geçerli kılar. Oturum kapatıldıktan sonra veya bir başka Query ekranı açıldığında bu tabloya erişilemez. SQL Serverda geçici tablolara sadece bulundukları ortamlardan erişilebilir. Temp Tabloların normal tablolardan en önemli farkı bir System Database olan tempdb içinde tutuluyor olmalarıdır.

Eğer temp table'a global olarak diğer ortamlardan da erişilmesini istiyorsak o zaman global temp table kullanmamız gerekmektedir. Global Temporary Tables (Genel geçici tablolar) tanımlamak için temp table dan farklı olarak CREATE TABLE dediktenden sonra tablomuzun ismini vermeden önce "##" işaretini 2 adet kullanarak bildirim yaparız. Global Temporary Tables'ın bütün özellikleri temp table ile aynıdır.

Genel Yapısı:
CREATE TABLE #TabloAdı (kolon1 veritipi, kolon2 veritipi)
--Local Temporary Table için "#" Global Temporary Table için "##" kullanılmalıdır.

Geçici tablolar tıpkı normal tablolar gibi oluşturulurlar sadece önlerinde "#" işareti farkı vardır. 

Örnek:
CREATE TABLE ##Musteriler(MusteriID NCHAR(5), MusteriAdSoyad NVARCHAR(30),
MusteriSehir NVARCHAR(15));
INSERT INTO ##Musteriler(MusteriID,MusteriAdSoyad,MusteriSehir)
SELECT Customers.CustomerID, ContactName, City
FROM Customers


Örneğimizde ##Musteriler adında bir Global Temporary Table oluşturduk. Query bağlantısında Northwind Database Customers tablosu örneklendi. Resimde görüldüğü gibi aktif database "BAYRAKTAR" olmasına rağmen global bir temporary table oluşturduğumuz için "select *  from ##Musteriler" ile listeleme yaptığımızda verilerin listelendiğini görüyoruz.

SQL Serverda "#" ile başlayan tablolar SQL Server durduğu ana kadar saklanır. Fakat tablolarımızı tempdb altına kendimiz normal tablo ekler gibi eklersek tablolarımız SQL Server kapatılana kadar orda saklanır. SQL Server kapatıldığında temp tablolarımızın silinmesini istiyorsak:
DROP TABLE #TemporaryTable

Temporary Tablolar Nerede ve Ne Amaçla Kullanılır?
Büyük veritabanları ile çalışırken bir sorgu sonucunda dönen kayıtları başka bir sorguda join işlemine tabi tutmak isteyebiliriz. Temporary Table kullanmak yerine iç içe SELECT sorguları yazılabilir ancak bu büyük kayıtlarda SQL Server üzerinde performans sıkıntısına neden olur. Bu nedenle belirli bir sorgu sonucunu Temporary bir tabloya atmak ve bu tabloyuda başka bir sorguda kullanabiliriz.

Değişken Tablolar (Table Variables)
Değişken tablolarda aslında geçici tablolara benzemektedir. Farkı oluşturduğumuz tablonun bir kısmı tempdb de bir kısmıda Sunucu olarak kullanıdığımız SQL Server belleğinde tutulmaktadır. Oluşturduğumuz tablo isminin başına "@" işareti koyarız. Değişken tablolara erişim temporary tablolara göre daha hızlıdır. Fakat değişken tablolara fazla veri yüklemek belleği dolduracağından performans kaybına yol açabilir. Değişken tabloların Temporary tablolardan en önemli farkı kullanıcı tanımlı fonksiyonlar (User Defined Functions) içinde kullanılabilmeleridir.

Genel Yapısı:
DECLARE @TabloAdı TABLE (kolon1 veritipi, kolon2 veritipi)
  • Değişken Tablolar tıpkı Temporary Tablolar gibi oluşturulurlar önlerinde "@" işareti farkı vardır. 
  • Değişken Tablolar üzerinde index tanımı yapamayız fakat geçici tablolar üzerinde yapabiliriz. 
  • Değişken tablolar üzerinde ALTER TABLE komutunu kullanamayız, yani bu şekilde oluşturulan bir tabloda ALTER TABLE işlemi yapılamıyor. Bu tipteki bir yapı çok fazla veri içermeyecek tablolar için uygundur.
Örnek:
DECLARE @Musteriler TABLE
(MusteriID NCHAR(5), MusteriAdSoyad NVARCHAR(30), MusteriSehir NVARCHAR(15))
INSERT INTO @Musteriler(MusteriID,MusteriAdSoyad,MusteriSehir)
SELECT Customers.CustomerID, ContactName, City
FROM Customers

SQL'de Transaction Oluşturma ve Kullanımı

Transaction  Nedir?
Transaction için SQL Server ortamında kullandığımız iş birimidir diyebiliriz. Çoğu zaman bir transaction yalnızca bir türde işlem yapar, yani sadece veri silme, veri güncelleme veya veri ekleme gibi tek türde işlem yapar. Ama bir transaction içinde birden fazla da işlem yapılabilir. Yine transaction içinde SELECT işlemleri de yapılabilmektedir. Transaction, çalışma yapısı olarak ya bütün işlemleri gerçekleştirir ya da hiçbirini gerçekleştirmez. İşlemlerden biri başarısız olursa, hiçbir işlem gerçekleşmez; ancak tüm işlemler başarılı olduğunda  Transaction, içinde gerçekleşen tüm veri değişikliklerini onaylamış demektir.  

Transaction bloğundaki işlemlerin hepsi başarılı olduğunda Transaction Commit (Onaylama) komutu çalışır ve değişiklikler veritabanında gerçekleşmiş olur. ancak bir hata varsa işleyiş bozulur ve Transaction Rollback (Geridönüş) komutu çalışır, bu şekilde tüm işlemler geri alınır ve en başa dönülür. Böylece veri kaybına karşı bir çeşit koruma mekanizması oluşturulmuş olunur.

Transaction  Nerde ve Ne Zaman Kullanırız
Örneğin veri tabanımızdan silinen kayıtları, başka bir veri tabanına yedekliyorsak. Bir silinme ve bir kaydetme işlemi söz konusu. Bu işlemlerin sırayla gerçekleşmesi gerekiyor. Silinme işlemi başarılı bir şekilde tamamlandı. Fakat kaydetme işleminde bir hata meydana geldi. Bu hata yetersiz hafızadan kaynaklanabilir, sistem işlem sırasında yeniden başlatılmıştır veya fiziksel bir arıza nedeniyle kapanmıştır. Bu nedenler yüzünden silinmiş kaydımıza elveda demek yerine, böylesi sorunlarla karşılaşma ihtimalimize karşı önlemimizi almamız gerekir. Çalışmasını istediğimiz kod bloğunu "transaction" bloklarına alırız ve sorun çözülmüş olur.

Şimdi örnekle konuyu pekiştirelim.

Örnek: Bir banka sisteminde para havale etme işlemi için örnek bir transaction tasarlayalım. Öncelikle aşağıdaki gibi bir "HESAP" tablosu oluşturalım ve tablomuzda müşterilere ait HESAP_ID, AD, SOYAD, HESAP_NO, BAKIYE bilgilerini tutalım. 
CREATE DATABASE BANKA
USE BANKA

CREATE TABLE HESAP
(
HESAP_ID INT PRIMARY KEY IDENTITY (1,1) NOT NULL,
AD       VARCHAR(30) NOT NULL,
SOYAD    VARCHAR(30) NOT NULL,
HESAP_NO INT         NOT NULL,
BAKIYE   INT         NOT NULL
)

Oluşturmuş olduğumuz "HESAP" tablomuza örnek kayıtlar girelim.
INSERT INTO HESAP VALUES('İBRAHİM','BAYRAKTAR',19265,7000)
INSERT INTO HESAP VALUES('SAMET','ULUTURK',19572,10000)
INSERT INTO HESAP VALUES('RAMAZAN','PINARBAŞI',19752,9500)
INSERT INTO HESAP VALUES('RAŞİT','BAKIR',19912,17000)

"Samet ULUTURK'ün hesabından, İbrahim BAYRAKTAR'ın hesabına 1000 TL havale yapılsın." Bu işlem için izleyeceğimiz algoritma Samet ULUTURK'ün bakiye bilgisini 1000 azaltmak ve İbrahim BAYRAKTAR'ın bakiye bilgisini 1000 artırmak olacaktır.
UPDATE HESAP SET BAKIYE = BAKIYE - 1000 --1.Sorgu
WHERE AD='SAMET' AND SOYAD='ULUTURK'

UPDATE HESAP SET BAKIYE = BAKIYE + 1000 --2.Sorgu
WHERE AD='İBRAHİM' AND SOYAD='BAYRAKTAR'
Havale işleminin gerçekleşmesi için bu iki sorgunun aynı anda gerçekleşmesi gerekir ve sistem kullanıcısı bu iki sorguyu birden çalıştırıyor. Şimdide örnek işlemimizde oluşabilecek olası hata senaryolarını inceleyelim.

Hata Olasılığı 1: Birinci SQL sorgumuzun çalışması fakat ikinci SQL sorgumuzda hata oluşması. Bu durumda Samet ULUTURK'ün hesabından 1000 TL eksilme olacak fakat İbrahim BAYRAKTAR'ın hesabında herhangi bir değişiklik olmayacaktır.

Hata Olasılığı 2: Birinci SQL sorgumuzda hata oluştu ve ikinci SQL sorgumuzun çalışması durumunda Samet ULUTURK'ün hesabından herhangi bir eksilme olmayacak fakat İbrahim BAYRAKTAR'ın hesabına 1000 TL eklenecek.

Örneğimizdeki gibi problemlerin ve olası hatalardan oluşacak karmaşanın önüne geçmek için  "transaction" yapısını kullanmalıyız. "transaction" sayesinde her iki sorguda birden çalıştıralacak, iki sorguda başarılı ise "transaction" onaylanacak fakat herhangi bir hata durumunda he iki sorguda iptal edilecek.

"transaction" yapısını SQL kodlarında kullanırken COMMIT ve ROLLBACK komutları kullanılır.

COMMIT komutu ile çalıştırılan tüm SQL komutlarının başarılı olması halinde işlemler veri tabanına yansıtılır. ROLLBACK komutu ise herhangi bir hata oluşumunda tüm işlemleri geri alır. 

Transaction  Oluşturalım
BEGIN TRANSACTION
BEGIN TRY

UPDATE HESAP SET BAKIYE = BAKIYE - 1000
WHERE AD='SAMET' AND SOYAD='ULUTURK'

UPDATE HESAP SET BAKIYE = BAKIYE + 1000
WHERE AD='İBRAHİM' AND SOYAD='BAYRAKTAR'

COMMIT
END TRY
BEGIN CATCH
ROLLBACK
END CATCH

"BEGIN TRANSACTION" ile "transaction" işlemini başlatıyoruz. Tek bir komut gibi çalışmasını istediğimiz SQL kodlarımızı yazdıktan sonra  "transaction" işlemini "COMMIT" ile sonlandırıyoruz. "COMMIT"  komutuna gelene kadar işlemde hata olsa da olmasa da, işlem sonuçları tablomuza yansımayacaktır. "END TRY" ile blogumuzu kapatıyoruz. İşlemde bir hata ile karşılaşılması durumunda "BEGIN CATCH" blogu devreye girecek ve "ROLLBACK" komutu ile yapılan işlemler geri alınacak.

SQL'de Türkçe Karakter Sorunu Nasıl Çözülür?

Eğer bir database tanımlaması düzgün yapılandırılmadıysa yeni oluşturduğunuz veya taşıdığınız veritabanındaki içeriklerde bulunan türkçe karakterler bozulabilir. Bunun nedeni veritabanını oluştururken seçmemiş olduğunuz veya default kalan "collation" ayarıdır. Eğer default değeriniz türkçe değilse tanımlama bozuk olacaktır. 

Bu sorunu düzeltmek için ne yapabiliriz?

Yeni bir veritabanı oluştururken ya da veritabanı taşırken yeni ekranında sol tarafta bulunan "Options" sekmesinde açılan "collation" öğesini "TURKISH_CI_AS" olarak seçmelisiniz.


"collation" değerini "TURKISH_CI_AS" olarak değiştirirseniz tanımlama anlamında herhangi bir karakter sorunu yaşanmayacaktır.

Varolan bir veritabanının tanımlama dilini kontrol etmek isterseniz. Object Explorer üzerinde kontrol etmek istediğiniz veritabanına sağ tıklayın. "Properties" seçin. Açılan "General" sekmesinde sağ tarafta altta Maintenance başlığında "Collation" kısmı bulunmaktadır. 

SQL'de VIEW Oluşturma ve Kullanımı

Temel amacı tabloların içerisinden veri kümesi getirip ortaya çıkan sonucu sanal tabloymuş gibi yeniden sorgulayabilmemizi sağlamaktır. Kısaca SQL'de verilerimizin isteğe bağlı alanlara ve tablolara göre ekranımızda görünteleme işlemi yapmamızı sağlar. Kullanıcının istediği verilere göre gösterim yapmak veya raporlamak SQL VIEW sayesinde kolaylıkla halledilmektedir.

Veritabanı VIEW ile oluşan datayı saklamaz. Bir VIEW geçen SQL deyimi her çalıştırıldığında ilgili VIEW sanal tabloyu yeniden oluşturur. VIEW üzerinde yapılan değişikler kendilerini oluşturan kaynak tabloları da etkiler ve aynı değişiklikler kaynak tablolara da yansır. VIEW kullanmanın önemli nedenlerinden bir tanesi sağladığı güvenliktir. Örneğin tablolarınızın tamanının görünmesini istemediğiniz zamanlarda sanal tablo kullanıp tablolarınızın tamamının görünmesini engelleyebilirsiniz. Karmaşık sorguları basitleştirmek, sorgu süresini kısaltmak ve ağ üzerindeki trafiği düşürmek, erişim izinlerini düzenlemek ve farklı sunuculardaki benzer verileri karşılaştırmak içinde kullanılır.
Oluşturulan VIEW'ler Object Explorer kısmında database/Views altında toplanır.

VIEW Oluşturma: VIEW oluşturmak için CREATE VIEW ifadesi kullanılır.

Genel Yapısı:
CREATE VIEW view_adı
AS
SELECT * FROM tablo_adi

Örnek1:
CREATE VIEW deneme_view
SELECT EmployeeID, FirstName, LastName
FROM Employees

Örneğimizde Northwind veritabanında Employees tablosundan sadece "EmployeeID, FirstName, LastName" kullanarak yeni bir view oluşturalım ve "select * from deneme_view" ile sorgumuzu çalıştıralım.

Örnek2:
CREATE VIEW deneme2_view
AS
SELECT FirstName,LastName
FROM Employees
WHERE FirstName LIKE 'a%'
WITH CHECK OPTION
Bu örneğimizde diğerinden farklı olarak bir şart belirttik ve WITH CHECK OPTION ifadesini kullandık.
WITH CHECK OPTION: SQL Server'da VIEW tanımlarken örneğimizdeki gibi WHERE anahtar sözcüğüyle bir şart belirtmiş olabiliriz. Böyle bir VIEW nesnesini kullanırken de VIEW üzerinden tablolarımıza "INSERT, UPDATE, DELETE" işlemleri gerçekleştirebiliriz. 

Şimdi diyelimki oluşturduğumuz VIEW'e bir INSERT yapmamız gerekti;
insert into deneme2_view values('Bayraktar','İbrahim')
eklenme yapılmak istendiğinde "The attempted insert or update failed because the target view either specifies WITH CHECK OPTION or spans a view that specifies WITH CHECK OPTION and one or more rows resulting from the operation did not qualify under the CHECK OPTION constraint. The statement has been terminated." hatasıyla karşılaşırız (VIEW oluştururken kullandığımız WITH CHECK OPTION ifadesinden dolayı 'a' ile başlamayan bir ekleme yapılamaz)

VIEW Silme: VIEW'leri silmek için DROP ifadesi kullanılır.

Genel Yapısı:
DROP VIEW view_adı
Örnek3:
DROP VIEW deneme2_view

VIEW Değişiklik Yapma: VIEW'ler üzerinde değişiklik yapmak için ALTER ifadesi kullanılır.

Genel Yapısı:
ALTER VIEW view_adı
WITH seçenekler
AS SELECT ifadesi

with schemabinding ifadesi ile kilitleme:
with schemabinding ifadesi VIEW'in bağlı olduğu tablodaki kolonları kilitleyip o kolonların silinmesini ve değişiklik yapılmasını engeller.

Genel Yapısı:
ALTER VIEW view_adı
WITH schemabinding
AS
SELECT ifadesi

Örnek3:
CREATE VIEW deneme3_view
WITH SCHEMABINDING --sütunla ilgili bir değişiklik yapılması engellenir
AS
SELECT FirstName,LastName,City
FROM dbo.EMPLOYEES


with encryption ifadesi ile gizleme: 
VIEW'leri şifreleyip sorguların görünür olmasını engeller. Kaynakların  gizliliğini sağlayan koddur, Kullanıcı sadece oluşturulan VIEW ile ilgili verilere erişebiliR kaynak tablolarla ilgili hiç bir bilgiye ulaşamaz.

Genel Yapısı:
ALTER VIEW view_adı
WITH encryption
AS
SELECT ifadesi

Örnek4:
CREATE VIEW deneme4_view
WITH ENCRYPTION --kaynak gizleme ve pasif design
AS
SELECT * FROM PRODUCTS

with encryption ifadesi kullanıldığında Object Explorer'da VIEW üzerinde kilit işareti belirir ve sağ click yapıldığından Design seçeneğinin pasifleştiğini görebiliriz.

SQL'de sp_helptext System Prosedürünün Kullanımı

sp_helptext prosedürü bizim tanımladığımız ya da sistemde bulunan objelerin tanımlamalarını text formatında gösterir. Böylece istediğimiz objenin tüm içeriğini nerede olduğunu aramadan direk  text içeriği ekrana döndürebiliriz.

Genel Yapısı:
exec sp_helptext '@objname'

Şimdi bir örnek ile olayı daha iyi kavrayalım. SP_ORNEK_1 sp'sinin içeriğini görüntülemek için;
use Northwind
exec sp_helptext 'SP_ORNEK_1'
yazmamış yeterli olacak. Bu komutun sonucunda ilgili Prosedürün text içeriği ekrana dökülür. SQL Server'da bir nesnenin SQL kodunu merak ediyorsanız sp_helptext bizim için en iyi araç. Tabi bu sp ile SQL Server'ın system sp, view ve diğer bileşenlerinin kodunu da görüntüleyebilirsiniz. Böylelikle merak ettiğiniz herhangi bir nesnenin nasıl kodlandığı incelenebilir.

use Northwind
exec sp_helptext 'Sales by Year'
Northwind veritabanı ile birlikte gelen "Sales by Year" isimli Prosedürün text içeriğini alalım.

SQL'de sp_help System Prosedürünün Kullanımı

sp_help System Prosedürü SQL'de  veritabanı ve sistem üzerindeki tüm tablolar, view ler, stored procedure ler gibi nesne tipleri hakkında ayrıntılı bilgi almamızı sağlar.

Genel Yapısı:
exec sp_help '@objname'

sp_help ile Nesneler hakkında bilgi almak için:  
use Northwind
exec sp_help
Örneklerde sıklıkla kullandığım Northwind veritabanındaki herbir objenin bilgilerini listeleyelim.

sp_help ile istenilen Obje hakkında bilgi almak için: 
use Northwind
exec sp_help 'Customers'
Northwind veritabanındaki Customers tablosu ile ilgili bilgileri listeleyelim.

SQL'de sp_rename System Prosedürü ile Nesne ismi Değiştirmek

sp_rename System Prosedürünü SQL'de  nesnelerimizin adlarını değiştirmek amacıyla kullanırız.

NOT: Oluşturulan her bir nesne nin bir id si vardır ve SQL Server'da nesneler id leri ile saklanırlar.

Genel Yapısı
exec sp_rename @object_name, @new_object_name, @object_type

sp_rename ile Tablo adının değiştirilmesi :   
use KITAPLAR
SELECT * FROM Fantastikkurgu

SELECT object_id('Fantastikkurgu')
exec sp_rename  'Fantastikkurgu','Bilimkurgu' 

--Fantastikkurgu tablomuz Bilimkurgu olarak değişecektir
işlem sonrasında SELECT * FROM Fantastikkurgu sorgusunu çalıştırdığımızda Invalid Object Name 'Fantastikkurgu' hatası döndürecektir.  Sorgumuzu SELECT * FROM Bilimkurgu olarak çalıştırdığımızda ise Fantastikkurgu tablosunda mevcut olan kolonları göreceksiniz. Benzer şekilde Object Explorer üzerinden tables'a refresh yaparsanız yine tablo adının değiştiğini görebilirsiniz.

object_id system function'ını kullanarak objenin id'sini öğrenebiliriz
object_id (objectname) null döndürüyorsa o isimde nesne ilgili database de yok demektir.
 
sp_rename ile Kolon adının değiştirilmesi :  
Yukarıdaki örnekte adını değiştirdiğimiz tablonun "Yazar" kolonunu "müellif" olarak değiştirelim. sp_rename prosedürünün default'u "object" olan bir parametresi daha var. Kolonlar, sysobjects de yer almazlar ve birer database objesi değillerdir ve tablo ismi olmadan da birşey ifade etmezler. x tablonun y kolonu diye saklanırlar ve çağırılırlar. Bu nedenle adını değiştirdiğimiz nesnenin kolon tipinde olduğunu ve hangi tabloya ait olduğunu da belirtmemiz gereklidir.

exec sp_rename 'Bilimkurgu.Yazar','müellif','COLUMN'
Bilimkurgu tablomuza ait olan Yazar isimli kolonu müellif olarak değiştirdik. SELECT * FROM Bilimkurgu  sorgusu ile kolon adının değiştiğini görebiliriz. 

sp_rename ile Veritabanı adının değiştirilmesi:
Veri tabanının adını değiştirmek için sp_renamedb prosedürü kullanılır.

sp_renamedb 'KITAPLAR', 'ESERLER' veya sp_renamedb KITAPLAR , ESERLER
“KITAPLAR” ismindeki veri tabanımızın yeni adı “ESERLER” olacaktır.

sp_rename ile Constraint (Kısıtlama) adının değiştirilmesi:
Constraint adı değiştirme tablo adı değiştirme ile aynıdır. Bir veri tabanında aynı isimde birden fazla tablo olamayacağı için aynı isimde birden fazla Constraint olamaz. Bu nedenle Constraint adını değiştirince hangi tabloya aittir diye bakmıyoruz.

CREATE TABLE [EPOSTA]
(
[ADI SOYADI] VARCHAR(50),
 EPOSTA VARCHAR(200)
 CONSTRAINT EPOSTA_KONTROL CHECK(EPOSTA LIKE '%@%.edu.tr')
)
Örnek EPOSTA tablomuzda EPOSTA_KONTROL adında bir constraint (kısıtlama) mevcut. Bu constraint eposta içinde "@" işareti var mı ve eposta adresi ".edu.tr" ile bitiyor mu diye kontrol ediyor. Bu constraint in adını değiştirmek için sp_rename kullanalım.

exec sp_rename EPOSTA_KONTROL, MAIL_KONTROL
"EPOSTA_KONTROL" olan constraint adı "MAIL_KONTROL" olarak değişecektir.

SQL Server'da Stored Procedure Temel Örnekler

okul adında bir veritabanı oluşturalım ve aktif çalışılacak şekilde belirleyelim.
CREATE DATABASE okul
USE okul

Oluşturduğumuz veritabanı içerinde ogrenci adında bir tablo yaratalım ve tabloya ait veri tiplerini belirleyelim.
CREATE TABLE ogrenci
(
adi nvarchar(20),
soyadi nvarchar(25),
ogr_no numeric(10),
bolum nchar(5),sehir nvarchar(30)
)

Oluşturduğumuz ogrenci tablomuzu kontrol amaçlı "liste" adında bir prosedür yazalım ve çalıştıralım.
CREATE PROCEDURE liste
AS
SELECT * FROM ogrenci

EXEC liste

Oluşturduğumuz ogrenci tablomuza  veri ekleme amaçlı "ekle" adında bir prosedür yazalım ve çalıştıralım.
CREATE PROCEDURE ekle
@isim nvarchar(20),
@sisim nvarchar(25),
@num numeric(10),
@bol nchar(5),
@il nvarchar(30)
AS
INSERT INTO ogrenci (adi,soyadi,ogr_no,bolum,sehir)
values(@isim,@sisim,@num,@bol,@il)


EXEC ekle 'İbrahim','BAYRAKTAR',3005,'BLG','YOZGAT'

Benzer şekilde eklediğimiz kayıtları silebilmek için bir "sil" prosedürü yazalım ve çalıştıralım.
CREATE PROCEDURE sil
@id numeric(10)
AS
DELETE FROM ogrenci WHERE ogr_no=@id

EXEC sil 3005

Eklemiş olduğumuz veriler üzerinde id belirterek kolaylıkla şehir kaydını değiştirebileceğimiz "guncelle" adında prosedürü yazalım ve çalıştıralım.
CREATE PROCEDURE guncelle
@il nvarchar(30),
@id numeric(10)
AS
UPDATE ogrenci SET sehir=@il
WHERE ogr_no=@id

EXEC guncelle 'ANKARA',3005

tablomuzda arama yapmak amacıyla kullanılacak basit bir arama prosedürü yazalım ve çalıştıralım.
CREATE PROCEDURE ara
@isim nvarchar(20)
AS
SELECT * FROM ogrenci  WHERE adi LIKE '%'+@isim+'%'

EXEC ara 'ib'

SQL Server'da Stored Procedure

Genel Yapısı
CREATE PROCEDURE veya CREATE PROC prosedürAdı
   [WITH Seçenekleri]
AS
   yazılacak procedure (SQL ifadeleri)
GO
CREATE PROCEDURE
veya
CREATE PROC
deyimi ile başlıyoruz ve prosedürümüzün ismini yazıyoruz.WITH seçeneği  stored procedure’un içinde bulunan kaynak kodlarını gizlemek için kullanılır. İsteğe bağlıdır. CREATE PROCEDURE ile AS deyimleri arasına parametreli stored prosedürler için değişken tanımlaması yapılır. Parametresiz prosedürler için herhangi bir tanımlama yapılmaz, AS yazılarak devam edilir. AS’den sonra prosedürün içine yazacağımız SQL ifadelerini yazarız ve GO deyimini de ekleyerek prosedürümüzü tamamlamış oluruz.  GO deyimi zorunlu değildir. Fakat genel kullanımda terchi edilmektedir.

Procedure yazıldıktan sonra çalıştırmak için "F5"
Stored Procedure'ümüzü tekrar çağırmak için:

EXEC prosedürAdı

Stored Procedure'ler SQL Serverda resimdeki konumda bulunmaktadır.


NOT: CREATE PROCEDURE ifadesinin altında CREATE DEFAULT, CREATE RULE, CREATE TRIGGER, CREATE VIEW ve CREATE PROCEDURE ifadeleri kullanılamaz. Bir stored procedure oluşturulurken, bu procedure'ün içinde DEFAULT, RULE, TRIGGER, VIEW ve başka bir PROCEDURE oluşturulamaz. Bir stored procedure yaratılırken içinde bu belirtilenler dışındaki objeler yaratılabilir.

NOT:  
Stored Procedure oluşturabilmek için: 
System Administrator (sysadmin) 
Database Owner (db_owner)
Data Definiton Language Administrator (db_ddladmin) 
rollerine yada CREATE PROCEDURE  izni verilmiş bir role sahip olunmalıdır.

İlk Procedure'ümüzü Yazalım ve Çalıştıralım


Stored Procedure Nedir?

Prosedür, belli bir işlevi yerine getirmek için özellikle yapılandırılmış program parçacıklarıdır. 

Stored Procedure Database de tutulan ve ilk derlemeden sonra bir daha derlenmeye ihtiyaç duyulmayan SQL ifadeleridir. Kısaca SQL Server üzerinde barındırılan, T-SQL komutları ile hazırladığımız işlemler bütününün çalıştırılma anında derlenmesi ile bize bir sonuç üreten SQL Server bileşenidir. SP olarak anılırlar.
  • Bir prosedür, başka bir prosedür içerisinde çağrılabilir.
  • Bir programlama dilindeki fonksiyonlar gibi parametre alabilirler. 
  • Bu parametrelere göre bir sorgu çalıştırıp cevap gönderilirebilir.  
  • Stored Procedure'ler database server'ında saklanmasından dolayı daha hızlı çalışırlar. 
  • Bir stored procedure ilk çalıştırıldığı zaman derlenir. Bir daha çalıştırılınca derlenmeden çalışırlar. 
  • Bir SQL komutu çağrıldığında ayrıştırma , derleme ve çalıştırma aşamalarından geçmektedir.
  • Stored Procedure'ler önceden derlenmiş olduğu için , normal kullandığımız bir SQL sorgusunda olduğu gibi bu 3 aşamadan geçmez, bu özelliği sayesinde programımızın performansı artmaktadır ve ağ trafiğini de azaltmış oluruz, istemci tarafından bir çok satıra sahip SQL komutunun sunucuya gitmesindense, sadece saklı yordamın adının sunucuya gitmesi ağı daha az meşgul etmiş olur. 
  • Bir kez yazıp tekrar ve tekrar kullandığımız için modüler bir yapıda program geliştirilmesi sağlanır. 
  • Stored Procedure'lerin diğer bir özelliği ise programlama deyimleri içermesidir. if, next, set vs..  
  • Stored Procedure'ler sadece giriş ve çıkış parametreleri uygulama katmanında göründüğü için daha güvenilirdir. 

Stored Procedure Tipleri : 
  • Extended Stored Procedure: DLL'ler tarafından, SQL Server dışında kullanılan stored procedure'lerdir. xp ifadesi ile başlayan bu tür stored procedure'ler, bazı system stored procedure'leri tarafından da çağrılarak kullanılabilir.
  • CLR Stored Procedure: CLR ortamında herhangi bir dili kullanarak da Stored Procedure'ler geliştirilen bir tür Stored procedure çeşididir.
  • Sistem Stored Procedure : sp_ ön eki ile başlarlar ve master veri tabanında tutulur.  
  • Kullanıcı Tanımlı Stored Procedure : Programcının programladığı stored procedurlerdir. 

SQL'de Yetkilendirme GRANT, DENY, REVOKE Kullanımları

DCL, bir veri tabanı ile ilişkili kullanıcıları ve rollerin izinlerini değiştirmek için kullanılır.
GRANT, DENY ve REVOKE temel DCL komutlarıdır.

DCL komutlarını kullanabilmek için SQL Server’da varsayılan değer (default) olarak yetki sahibi olan gruplar:
sysadmin , dbcreator , db_owner , db_securityadmin ‘dir.

Öncelikle sunucuya dışarıdan bir erişim sağlamak için bir giriş (login) oluşturulmalıdır.

CREATE LOGIN BAYRAKTAR WITH PASSWORD="QWERTY123"
komutuyla "QWERTY123" şifresine sahip BAYRAKTAR adında bir kullanıcı oluşturduk.

Şimdi bu login üzerinden bir kullanıcı yaratalım ve GRANT, DENY, REVOKE kullanımlarını inceleyelim.

CREATE USER BAYRAKTAR FOR LOGIN BAYRAKTAR
User oluşturmuş olduk.

GRANT: Kullanıcılara veritabanı nesneleri üzerinde güvenlik ayrıcalıkları vermek için kullanılan komuttur.

Genel yapısı şu şekildedir: GRANT (all | izinler) ON (izneTabiTutulanlar) TO (izinVerilenler)

GRANT CREATE TABLE TO BAYRAKTAR  
BAYRAKTAR kullanıcısına tablo oluşturma yetkisi veriyoruz.

GRANT INSERT,UPDATE,DELETE TO BAYRAKTAR
BAYRAKTAR kullanıcısına güncelleme, silme ve ekleme yetkisi veriyoruz.

GRANT SELECT ON Bilimkurgu TO BAYRAKTAR
BAYRAKTAR kullanıcımızın "Bilimkurgu" tablosundan select çekebilmesine izin verelim.

WITH GRANT OPTION: Dereceli yetkilendirme işleminde kullanılır. Yetki verilmiş kullanıcının kendisinde bulunan yetkileri başka kullanıcılara verebilmesini sağlar.

GRANT SELECT,INSERT ON Bilimkurgu TO BAYRAKTAR WITH GRANT OPTION
BAYRAKTAR kullanıcısına bilimkurgu tablosu üzerinde select ve insert hakkı veriyoruz. Ama with grant option ifadesinden dolayı, BAYRAKTAR kullanıcısı da, başkasına da bu yetkiyi verebilir.

DENY: GRANT komutunun tersidir. Yetkileri engeller.

Genel yapısı şu şekildedir: DENY (ALL | izinler) TO (izinVerilenler) 

DENY CREATE TABLE TO RAMAZAN
RAMAZAN kullanıcısına tablo yaratmayı yasakladık.

DENY INSERT, SELECT ON Bilimkurgu TO RAMAZAN
RAMAZAN kullanıcısının bilimkurgu tablosunda INSERT ve SELECT kullanmasını engelledik.


REVOKE: GRANT ile değiştirdiğimiz hakları eski haline döndürmek için kullanılır. Bir nesneyi oluşturan kullanıcının REVOKE ile nesne üzerindeki yetkilendirme ve kullanma hakkı yok edilemez. 

Genel yapısı şu şekildedir:  REVOKE (all | izinler) TO/FROM (izinVerilenler)

REVOKE ALL ON REGION TO BAYRAKTAR
BAYRAKTAR kullanıcısına verilen tüm yetkileri kaldırır.

SQL'de Constraint (Kısıtlayıcı) ve Constraint Türleri

Constraint (Kısıtlayıcı): Veri üzerindeki mantıksal sınırlamalara kısıt adı verilir. Bu kısıtlamalar veritabanına eklenebilecek ya da bir güncellemeyle değiştirilebilecek veri değerlerini sınırlar. Kısıtlamalar, tabloların tanımlanmasıyla beraber oluşan öğelerdir. Kısıtlamalar ile Rule (kural) ve Default’ların (varsayılan) yapabileceği işler yapılabilir. 

Constraintler tablo oluştururken CREATE TABLE komutuyla tanımlanabilir. 
Tablo oluşturulmuşsa ALTER TABLE komutuyla bu işlem gerçekleşir. 

Constraint Türleri

Primary Key Constraint: Birincil anahtar kısıtlayıcı anlamındadır. Her kaydın farklı olması demektir. Her tablonun en fazla 1 adet Primary Key Constraint’i olabilir.

Unique Constraint: Tekil alan kısıtlayıcı anlamındadır. Birincil anahtar olan ve tablodaki diğer alanlar içinde aynı içeriğe sahip verilerin olmaması için Unique Constraint tanımlanır. T.C.Kimlik Numarası. Primary Key ve Hasta Dosya No Unique şeklinde bir tanımlama Unique Constraint’e bir örnektir.

Foreign Key Constraint: Yabancıl anahtar kısıtlayıcı anlamındadır. Bir tablodaki bir sütuna ait verilerin başka bir tablonun belirli bir sütunundan gelmesini denetler. Sadece bağladığımız sütundaki değerleri içerebilir.

Default Constraint: Varsayılan kısıtlayıcı anlamındadır. Tablodaki herhangi bir alan için girilmesi gereken bir değerin atanmasıdır. INSERT komutu için geçerlidir. Örneğin, kişi bilgilerinin alındığı bir tabloda kişinin uyruğunun girilmesi işleminde varsayılan değer olarak "T.C." atanabilir.

Check Constraint: Kontrol kısıtlacıyı anlamındadır. Belirtilen formata göre verilerin girilmesini sağlar. T.C. numara alanına 11 karakterin girilmesi ve konrolü Check Constraint ile sağlanabilir.

Constraint Örnek:


Örneğimizi inceleyelim. 

İlk olarak CREATE DATABASE CONSORNEK - "CONSORNEK" adında bir database oluşturuyoruz.

USE CONSORNEK ile işlem yapacağımız database'i seçili hale getiriyoruz.

CREATE TABLE HASTA
(
HASTA_NO INT PRIMARY KEY IDENTITY(1,1),
AD NVARCHAR(25),
SOYAD NVARCHAR(25),
DOGUMTARIHI DATE,
CONSTRAINT YASKISITLA Check(DATEDIFF(YEAR,DOGUMTARIHI,GetDate())>18 and DATEDIFF(YEAR,DOGUMTARIHI,GetDate())<75)
)

işlem tablomuzu ve sutunlarımızı oluşturup veri tiplerini belirliyoruz. 
Son satırda Constraint’imizi yani kısıtımızı"YASKISITLA" ismiyle belirtiyoruz.

INSERT HASTA (AD,SOYAD,DOGUMTARIHI) 
VALUES ('IBRAHIM','BAYRAKTAR','05.08.1982')

INSERT komutuyla tablomuza ve veritiplerine uygun değerleri giriyoruz.

Örnekte kısaca HASTA tablosuna kayıt işlemi yaptırıyoruz. Fakat tanımladığımız Constrait ile sadece 18/75 yaş aralığında kişilerin kaydına izin verilmesini sağlıyoruz.

SQL'de Foreign Key Kullanımı

  • SQL'de bir başka tablo ile ilişkilendirilecek olan tablonun diğer tabloda bir nevi kısıtlanmasıdır. İlişkilendirilecek olan tablonun Primary key alanı ile diğer tablonun Foreign key alanı birbiri ile bağlanır.
  • Foreign Key kısıtlaması sütunlarından herhangi biri null değerler içeriyorsa, Foreign Key kısıtlamasını oluşturan tüm değerlerin doğrulaması atlanır.
  • Foreign Key kısıtlamasının yalnızca başka bir tablodaki Primary Key kısıtlamasına bağlı olmasına gerek yoktur. Ayrıca başka bir tablodaki UNIQUE kısıtlama sütununa başvuracak şekilde de tanımlanabilir.
Foreign Key tanımlamak için, tablomuzdaki Foreign Key olacak sütunu yazdıktan sonra REFERENCES yazıp bağlanacak tablounun adını ve parantez içindede ilgili sütunu yazarız.

CREATE TABLE SIPARISLER
(
Siparis_ID integer primary key,
Siparis_Tarihi datetime,
Musteri_SID integer REFERENCES MUSTERI(SID),
Tutar double
)

SQL'de Primary Key Kullanımı

  • Primary Key ile veritabanımızdaki tablolarda, primary key atanmış olan sütun (kolon) ile birlikte eşsiz şekilde verilere sahip satırlar oluşturabiliriz. 
  • Primary Key olan alanlar Null değerler olamaz ve bu bölüme aynı değerler girilemez. 
  • Tablolarımızda mutlaka Primary Key kullanmak çok büyük avantaj sağlayacaktır.
  • Primary Key (Birincil Anahtar) genelde otomatik artan değerler olarak kullanılır. Bu otomatik artma da identity komutu ile gerçekleştirilir. 
  • Primary Key tanımlamak aslında bir nevi Constraint‘tir yani bir nevi kısıtlama yapmaktır.
  • Bir tabloda sadece bir Primary Key bulunur ama bununla birlikte tabloda birden fazla kolon için bileşik anahtar yani composite key oluşturulabilir. 
  • Eğer primary key bir composite key yani bileşik anahtar ise, tüm değerlerin kombinasyonu unique yani eşsiz olmalıdır. 
Daha basitce açıklamak gerekirse örneğin bir HBYS veritabanında Hastalar tablomuz mevcut, oldukca çok veri içeren bir tablo. Aynı ad ve soyada sahip birçok kişi var. Şimdi bu verileri en basit şekilde nasıl birbirlerinden ayırt ederiz. TC Kimlik No, aynı TC Kimlik Numarasının ikinci bir kişide olması mümkün değildir. Veritabanımızda TC Kimlik No alanını Primary Key olarak tanımlayarak eşsiz veriler oluşturabiliriz. Primary Key tablomuzdaki kayıtları sütün aracılığıyla eşşiz kayıt haline getirmemizi sağlayacaktır.

Yeni bir Alanda Primary Key Kullanımı:
CREATE TABLE Yazarlar
(
id int NOT NULL PRIMARY KEY,
adi_soyadi varchar(20) ,
Yayinevi varchar(20)
)

Yeni birden fazla Alanda Primary Key Kullanımı:
CREATE TABLE Yazarlar
(
id int NOT NULL,
adi_soyadi varchar(20) NOT NULL ,
Yayinevi varchar(20),
CONSTRAINT id_no PRIMARY KEY  (id,adi_soyadi)
)

Varolan bir Alanda Primary Key Kullanımı:
ALTER TABLE Yazarlar
ADD PRIMARY KEY (id)

Varolan birden fazla Alanda Primary Key Kullanımı:
ALTER TABLE Yazarlar
ADD CONSTRAINT  id_no PRIMARY KEY (id,adi_soyadi)

NOT: ALTER ile sonradan bir alana PRIMARY KEY kriteri tanımlanırken ilgili alanda veya alanlarda NULL yani boş kayıt olmamalıdır.

PRIMARY KEY yapısını kaldırmak:
ALTER TABLE Yazarlar
DROP CONSTRAINT id_no

NOT: Birden fazla alanda PRIMARY KEY işlemi yaptıysak, CONSTRAINT ifadesinden sonra tablomuzdaki alan adı değil, oluşturduğumuz index adı yazılmalıdır.