- SQL Server adı üstünde bir server'dır. Access gibi sadece bir veri tutan yapı değildir. Server olduğundan dolayı üzerinde birden fazla yapı çalışmaktadır. Bunlardan bir tanesi de database dediğimiz veritabanıdır.
-
Transact SQL(T-SQL) Dili Ozellikleri
-
Yorum Satiri -- ifadesidir.
-
T-SQL ile veri cekme, kaydetme, guncelleme, ve silme gibi islemlerle veritabanina mudahale edebilir, database olusturma - silme, tablo olusturma - silme islemlerinin gerceklestirebilir ve diger veritabani yapilari ve programatik islemlerde kullanacagimiz veritabani programlama araclarını olusturabiliriz.
-
T-SQL buyuk kucuk harf duyarliligina sahip bir dil degildir. --MUSA = Musa = MuSa
-
T-SQL programlama dili bizim icin veritabanina belirli bir yaklasim sergilememizi saglayan gramersel bir dildir.
-
T-SQL komutları ne yazarsak yazalım belirli bir veritabani uzerinde calisacaktir ve T-SQL komutlarini calistiracagimiz veritabanini bir yerde belirlememiz gerekir. Neden? Server'da birden fazla veritabani bulunabiliyor. Haliyle burada yazdigim TSQL komutlarinin hangi veritabaninda calisacagina belirlemem gerekmektedir.
-
Komutlarla veritabanını secmek icin
USE
komutunu kullanırız.
USE Northwind
USE Northwind
- SELECT KOMUTU
- Verdiğimiz herhangi bir değeri bize tablo olarak döndüren bir komuttur.
SELECT 3
SELECT 'MUSA'
PRINT 'MUSA'
SELECT 3,5,7
SELECT 'MUSA', 'UYUMAZ',24
*
Karakteri tablonun içerisindeki bütün kolonları ifade eden bir karakterdir.
SELECT * FROM Personeller
SELECT Adi,SoyAdi FROM Personeller
-
ALIAS ATAMA
-
Ben bir tabloyu
SELECT
ile çektiğim zaman tablo içindeki kolonların isimleri neyseSELECT
in sonuç olarak oluşturduğu tabloda o kolon isimleri fiziksel kolondakilerle aynıdır. Haliyle ben buradaki isimleri değiştirebilirim. -
Yani kolona bir nitelik atıyoruz.
SELECT 3 AS DEĞER
SELECT 3 DEĞER
SELECT 'MUSA' ADI, 'UYUMAZ' SOYADI
SELECT Adi İSİMLER, SoyAdi SOYİSİMLER FROM Personeller
- Boşluk Karakteri Olan Alias Atama
SELECT 1453 İSTANBULUN FETHİ
SELECT 1453 [İSTANBULUN FETHİ]
-Boşluk Karakteri Olan Tabloyu Sorgulama
SELECT * FROM Satis Detaylari
SELECT * FROM [Satis Detaylari]
- Kolonları Birleştirme
SELECT Adi,SoyAdi FROM Personeller
SELECT Adi + ' ' + SoyAdi [PERSONEL BİLGİLERİ] FROM Personeller
-
Farklı Tipte Kolonları Birleştirme
-
İki farklı tipteki kolon direkt olarak
+
operatörü ile birleştirilemez. Bu yüzden birleştirme işleminde aynı türe dönüştürmek gerekir
SELECT Adi + ' ' + IseBaslamaTarihi FROM Personeller
SELECT Adi + ' ' + CONVERT(NVARCHAR, IseBaslamaTarihi) FROM Personeller
SELECT Adi + ' ' + CAST(IseBaslamaTarihi AS NVARCHAR) FROM Personeller
USE Northwind
- SELECT sorgularında elde ettiğimiz tablolara belirli şartlar yazmamızı sağlar.
SELECT * FROM Personeller
- Personeller tablosunda şehri London olanları listeleyelim.
SELECT * FROM Personeller WHERE Sehir = 'London'
- Personeller tablosunda bağlı çalıştığı kişi sayısı 5'ten küçük olanları listeleyelim.
SELECT * FROM Personeller WHERE BagliCalistigiKisi < 5
- Personeller tablosunda şehri London ve ülkesi UK olanları listeleyelim.
SELECT * FROM Personeller WHERE Sehir = 'London' AND Ulke='UK'
-- Personeller tablosunda UnvanEki 'Mr.' olan veya şehri Seattle olan tüm personelleri listeleyelim.
SELECT * FROM Personeller WHERE UnvanEki = 'Mr.' OR Sehir = 'Seattle'
- Adı Robert soyadı King olan personelin tüm bilgilerini çek
SELECT * FROM Personeller WHERE Adi='Robert' AND SoyAdi='King'
- PersonelID'si 5 olan personeli getir.
SELECT * FROM Personeller WHERE PersonelID=5
- PersonelID'si 5'ten büyük ve eşit olan tüm personelleri getir.
SELECT * FROM Personeller WHERE PersonelID >=5
<>
Eşit Değilse=
Eşitse<=
Küçük ve Eşitse>=
Büyük ve Eşitse
- 1993 yılında işe başlayanları listele.
SELECT * FROM Personeller WHERE YEAR(IseBaslamaTarihi)=1993
- 1992 yılından sonra işe başlayanları listele
SELECT * FROM Personeller WHERE YEAR(IseBaslamaTarihi)>1992
- Doğum günü ayın 29'u olmayan personelleri listeleyelim
SELECT * FROM Personeller WHERE DAY(DogumTarihi) <> 29
- Doğum yılı 1950 ile 1965 yılları arasında olan personelleri getirelim
SELECT * FROM Personeller WHERE YEAR(DogumTarihi) BETWEEN 1950 AND 1965
SELECT * FROM Personeller WHERE YEAR(DogumTarihi)> 1950 AND YEAR(DogumTarihi) < 1965
- Yaşadığı şehrin London, Tacoma ve Kirkland olan personellerin adını listeleyelim
SELECT Adi FROM Personeller WHERE Sehir IN('London','Tacoma','Kirkland')
SELECT Adi FROM Personeller WHERE Sehir ='London' OR Sehir = 'Tacoma' OR Sehir = 'Kirkland'
-
Eğer ki WHERE şartı ile belirli bir değer aralığını belirtilecekse yani şartımız belirli bir değer aralığıysa eğer BETWEEN komutu ile daha pratik şekilde şartımızı yazabiliriz.
-
Doğum yılı 1950 ile 1965 yılları arasında olan personelleri getirelim
SELECT * FROM Personeller WHERE YEAR(DogumTarihi) BETWEEN 1950 AND 1965
-
Bir kolonda OR komutunu kullanarak yaptığımız şartları IN komutu ile daha pratik bir şekilde yapabilmekteyiz.
-
Yaşadığı şehrin London Tacoma ve Kirkland olan personellerin adlarını listeleyelim.
SELECT Adi FROM Personeller WHERE Sehir IN('London','Tacoma','Kirkland')
- Veriler içerisinde belirli şartlar koyabildiğimiz bir sorgulama çeşididir.
- WHERE'de kolonlara belirli şartlar koyarken LIKE sorgusuyla birlikte kolonlar içerisindeki verilere şartlarımızı koyabiliriz.
- İsminin baş harfi j olan personellerin adını soyadını yazdıralım
SELECT Adi,SoyAdi FROM Personeller WHERE Adi LIKE 'j%'
- İsminin son harfi y olan personellerin adını soyadını yazdıralım
SELECT Adi,SoyAdi FROM Personeller WHERE Adi LIKE '%y'
- İsminin son üç harfi ert olan personeli getirelim
SELECT * FROM Personeller WHERE Adi LIKE '%ert'
- İsminin ilk harfi r, son harfi t olan personeli getirelim
SELECT * FROM Personeller WHERE Adi LIKE 'r%t'
- Gereksiz bir kullanım
SELECT * FROM Personeller WHERE Adi LIKE 'r%' AND Adi LIKE '%t'
- İsminde an geçen personelin adını yazdıralım
SELECT Adi FROM Personeller WHERE Adi LIKE '%an%'
- İsminin baş harfi n olan ve içerisinde an geçen personeli getirelim.
SELECT * FROM Personeller WHERE Adi LIKE 'n%an%'
- Gereksiz Bir kullanım
SELECT * FROM Personeller WHERE Adi LIKE 'n%' AND Adi LIKE '%an%'
-
O anki karakterin önemli olmadığını belirtir.
-
İsminin ilk harfi a ikinci harfi farketmez ve üçüncü harfi d olan personeli getirelim
SELECT * FROM Personeller WHERE Adi LIKE 'a_d%'
- İsminin ilk harfi m ikinci,üçüncü,dördüncü farketmez ve beşinci harfi a olan personeli getirelim
SELECT * FROM Personeller WHERE Adi LIKE 'm___a%'
-
Arka planda OR mantığıyla çalışır
-
İsminin ilk harfi n ya da m ya da r olan personelleri getirelim
SELECT * FROM Personeller WHERE Adi LIKE '[nmr]%'
- İsminin içerisinde a ya da i geçen personelleri getirelim
SELECT * FROM Personeller WHERE Adi LIKE '%[ai]%'
-
iki harf arasındaki tüm harfleri kapsayan bir operatördür.
-
İsminin baş harfi a ile k arasında alfabetik sıraya göre herhangi bir harf olan personellerin adını yazdıralım
SELECT Adi FROM Personeller WHERE Adi LIKE '[a-k]%'
- O anki bulunduğumuz karakterin değilini ifade eder.
- İsminin baş harfi a olmayan personelleri getirelim.
SELECT * FROM Personeller WHERE Adi LIKE '[^a]%'
- İsminin baş harfleri an olmayan personelleri getirelim
SELECT * FROM Personeller WHERE Adi LIKE '[^an]%'
- LIKE sorgularında kullandığımız %, _, [] gibi özel ifadeler eğer ki verilerimiz içerisinde geçiyorsa sorgulama esnasında hata ile karşılaşabiliriz. Böyle durumlarda bu ifadelerin özel ifade olmadığını escape karakterleri ile belirleyebiliriz.
SELECT * FROM Personeller WHERE Adi LIKE '[_]%'
SELECT * FROM Personeller WHERE Adi LIKE '?_%' ESCAPE '?'
-
Tüm veriler tüm satırlar üzerinde işlem yapmamızı sağlayan fonksiyonlardır.
-
AVG : Ortalama alır.
SELECT AVG(PersonelID) FROM Personeller
- MAX : En büyük değeri bulur.
SELECT MAX(PersonelID) FROM Personeller
- MIN : En küçük değeri bulur.
SELECT MIN(PersonelID) FROM Personeller
- COUNT : Toplam sayısını verir.
SELECT COUNT(*) FROM Personeller
SELECT COUNT(Adi) FROM Personeller
- SUM : Toplamını verir.
SELECT SUM(NakliyeUcreti) FROM Satislar
-
Metinsel değerler üzerinde işlem yapmamızı sağlayan fonksiyonlardır.
-
LEFT : Soldan(baştan) belirtilen sayıda karakteri getirir.
SELECT LEFT(Adi,2) FROM Personeller
- RIGHT : Sağdan(sondan) belirtilen sayıda karakteri getirir.
SELECT RIGHT(Adi,3) FROM Personeller
- UPPER : Büyük harfe çevirir.
SELECT UPPER(Adi) FROM Personeller
- LOWER : Küçük harfe çevirir.
SELECT LOWER(Adi) FROM Personeller
- SUBSTRING : Belirtilen index'ten itibaren belirtilen sayıda karakter getirir
SELECT SUBSTRING(SoyAdi,3,2) FROM Personeller
- LTRIM : Soldan boşlukları keser.
SELECT ' MUSA'
SELECT LTRIM(' MUSA')
- RTRIM : Sağdan boşlukları keser.
SELECT 'UYUMAZ '
SELECT RTRIM('UYUMAZ ')
- REVERSE : Tersine çevirir.
SELECT REVERSE(Adi) FROM Personeller
- REPLACE : Belirtilen ifadeyi belirtilen ifade ile değiştirir.
SELECT REPLACE('Benim Adım MUSA', 'MUSA','SERHAT')
- CHARINDEX : Belirtilen karakterin veri içinde sıra numarasını verir.
- Index numarasını değil sıra numarasını verir!!!
SELECT Adi,CHARINDEX('r',Adi) FROM Personeller
SELECT MusteriAdi, CHARINDEX(' ',MusteriAdi) FROM Musteriler
- CHARINDEX Örnek
- Müşteriler tablosunun MusteriAdi kolonundan sadece adları çekelim.
SELECT MusteriAdi FROM Musteriler
SELECT MusteriAdi,LEFT(MusteriAdi,CHARINDEX(' ',MusteriAdi)) FROM Musteriler
SELECT SUBSTRING(MusteriAdi,0, CHARINDEX(' ',MusteriAdi)) FROM Musteriler
- Müşteriler tablosunun MusteriAdi kolonundan sadece soyadları çekelim.
SELECT SUBSTRING(MusteriAdi, CHARINDEX(' ', MusteriAdi),LEN(MusteriAdi) - (CHARINDEX(' ', MusteriAdi) - 1)) FROM Musteriler
SELECT 3 + 2
SELECT 3 * 3
SELECT 4 / 2
SELECT 9 - 7
PI
: Pi sayısını verir.
SELECT PI()
SIN
: Sinüs alır.
SELECT SIN(PI())
SELECT SIN(90)
POWER
: Üs alır.
SELECT POWER(2,3)
ABS
: Mutlak değer alır.
SELECT ABS(-12)
RAND
: 0 - 1 arasında rastgele sayı üretir.
SELECT RAND()
FLOOR
: Yuvarlama yapar.
SELECT FLOOR(RAND() * 100)
SELECT ROUND(RAND() * 10,0)
- GETDATE : Bugünün tarihini verir.
SELECT GETDATE()
- DATEADD : Verilen tarihe verildiği kadar gün, ay, yıl ekler
SELECT DATEADD(DAY,999,GETDATE())
SELECT DATEADD(MONTH,999,GETDATE())
SELECT DATEADD(YEAR,999,GETDATE())
- DATEDIFF : İki tarih arasında günü, ayı veya yılı hesaplar.
SELECT DATEDIFF(DAY,'14.02.1999',GETDATE())
SELECT DATEDIFF(MONTH,'14.02.1999',GETDATE())
SELECT DATEDIFF(YEAR,'14.02.1999',GETDATE())
- DATEPART : Verilen tarihin haftanın, ayın yahut yılın kaçıncı günü olduğunu hesaplar
SELECT DATEPART(DW,GETDATE())
SELECT DATEPART(MONTH,GETDATE())
SELECT DATEPART(DAY,GETDATE())
- SELECT sorgusu neticesinde elde ettiğimiz tablodan ilk kaç kaydın gösterileceğini belirlememizi sağlar.
SELECT TOP 3 * FROM Personeller
- Bir kolondaki benzer olan verileri teke indirmemizi sağlayan bir komuttur.
SELECT DISTINCT Sehir FROM Personeller
- Eğer ki SELECT sorgusunda bir normal kolon bir de ayriyetten aggregate fonksiyonu çağırılıyorsa normal olan kolonu gruplamanız gerekecektir.
SELECT KategoriID,COUNT(*) FROM Urunler
GROUP BY KategoriID
SELECT PersonelID,COUNT(*) FROM Satislar
GROUP BY PersonelID
SELECT PersonelID,SUM(NakliyeUcreti) FROM Satislar
GROUP BY PersonelID
- Grammer'de WHERE şartı GROUP BY'dan önce yazılmalıdır.
SELECT KategoriID,COUNT(*) FROM Urunler WHERE KategoriID > 5 GROUP BY KategoriID
SELECT PersonelID,COUNT(*) FROM Satislar WHERE PersonelID < 4 GROUP BY PersonelID
-
WHERE normal kolonlar üzerinde şart uygulayacağımız zaman kullandığımız bir komuttur. Lakin HAVING aggregate fonksiyonu üzerinde şart uygulayacaksak kullandığımız bir komuttur.
-
HAVING komutu GROUP BY'dan sonra yazılır.
SELECT KategoriID,COUNT(*) FROM Urunler WHERE KategoriID > 5 GROUP BY KategoriID HAVING COUNT(*) > 6
- Her bir satıra eş değer farklı bir satır türetiyor türetemediklerine de null değer atıyor.
SELECT * FROM Personeller
SELECT * FROM Satislar
SELECT * FROM Personeller P,Satislar S WHERE P.PersonelID = s.PersonelID
- Birden fazla tabloyu ilişkisel kolonlar aracılığıyla birleştirip tek bir tablo haline getiren bir yapıdır.
-
SELECT * FROM Tablo1 INNER JOIN TABLO2 ON Tablo1.IlişkiliKolon = Tablo2.IlişkiliKolon
-
Tablolara alias tanımlanabilir.
-
SELECT * FROM Tablo1 T1 INNER JOIN TABLO2 T2 ON T1.IlişkiliKolon = T2.IlişkiliKolon
- Hangi personel hangi satışları yapmıştır. (Personeller, Satışlar)
SELECT * FROM Personeller P INNER JOIN Satislar S ON P.PersonelID = S.PersonelID
- Hangi ürün hangi kategoride. (Urunler, Kategoriler)
SELECT U.UrunAdi,K.KategoriAdi FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID
- Beverages Kategorisindeki ürünlerim. (Urunler, Kategoriler)
SELECT U.UrunAdi FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID WHERE K.KategoriAdi = 'Beverages'
- Beverages kategorisindeki ürünlerimin sayısı kaçtır. (Urunler, Kategoriler)
SELECT COUNT(U.UrunAdi) FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID WHERE K.KategoriAdi = 'Beverages'
- Seafood kategorisindeki ürünlerin listesi (Urunler, Kategoriler)
SELECT U.UrunAdi FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID WHERE K.KategoriAdi = 'Seafood'
- Hangi Satışı hangi çalışanım yapmış? (Satışlar, Personeller)
SELECT S.SatisID, P.Adi + ' ' +P.SoyAdi FROM Satislar S INNER JOIN Personeller P ON P.PersonelID = S.PersonelID
- Faks numarası 'NULL' olmayan tedarikçilerinden alınmış ürünler nelerdir? (Urunler, Tedarikçiler)
SELECT U.UrunAdi FROM Urunler U INNER JOIN Tedarikciler T ON T.TedarikciID = U.TedarikciID WHERE T.Faks <> 'NULL'
SELECT U.UrunAdi FROM Urunler U INNER JOIN Tedarikciler T ON T.TedarikciID = U.TedarikciID WHERE T.Faks IS NOT NULL
-
İkiden fazla tabloyu ilişkisel bir şekilde birleştirme yöntemine giderken dikkat etmemiz gereken nokta birleştirme esnasında birleştirdiğimiz tablonun diğer tabloyla ortak olan bir ilişkisel kolona ait olması gerekmektedir.
-
1997 yılından sonra Nancy'nin satış yaptığı firmaların isimleri : (1997 dahil) (Musteriler, Satislar, Personeller)
SELECT M.SirketAdi FROM Musteriler M INNER JOIN Satislar S ON M.MusteriID = S.MusteriID INNER JOIN Personeller P ON P.PersonelID = S.PersonelID WHERE P.Adi = 'Nancy' AND YEAR(S.SatisTarihi) >= 1997
- Limited olan tedarikçilerden alınmış Seafood kategorisindeki ürünlerimin toplam satış tutarı. (Urunler, Kategoriler, Tedarikçiler)
SELECT SUM(U.BirimFiyati * U.HedefStokDuzeyi) FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID INNER JOIN Tedarikciler T ON T.TedarikciID = U.TedarikciID WHERE K.KategoriAdi = 'Seafood' AND T.SirketAdi LIKE '%Ltd.%'
- Personellerimin bağlı olarak çalıştığı kişileri listele? (Personeller, Personeller)
SELECT P1.Adi, P2.Adi FROM Personeller P1 INNER JOIN Personeller P2 ON P1.BagliCalistigiKisi = P2.PersonelID
- Hangi personelim(adı ve soyadı ile birlikte) toplam kaç adetlik satış yapmış. Satış adedi 100'den fazla olanlar ve personelin adının baş harfi M olan kayıtlar gelsin. (Personeller, Satışlar)
SELECT P.Adi + ' ' + P.SoyAdi ,COUNT(S.SatisID) FROM Personeller P INNER JOIN Satislar S ON S.PersonelID = P.PersonelID WHERE P.Adi LIKE 'M%'
GROUP BY P.Adi + ' ' + P.SoyAdi
HAVING COUNT(*) > 100
- Seafood kategorisindeki ürünlerin sayısı (Urunler, Kategoriler)
SELECT COUNT(*) FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID
WHERE K.KategoriAdi = 'Seafood'
- Hangi personelim toplam kaç adet satış yapmış (Personeller, Satışlar)
SELECT P.Adi,COUNT(S.SatisID) FROM Personeller P INNER JOIN Satislar S ON S.PersonelID = P.PersonelID
GROUP BY P.Adi
- En çok satış yapan personelim (Personeller, Satışlar)
SELECT TOP 1 P.Adi,COUNT(S.SatisID) FROM Personeller P INNER JOIN Satislar S ON S.PersonelID = P.PersonelID
GROUP BY P.Adi
ORDER BY COUNT(S.SatisID) DESC
- Adında 'a' harfi olan personellerin satış id'si 10500'den büyük olan satışlarının toplam tutarını(miktar * birim fiyat) ve bu satışların hangi tarihte gerçekleştiğini listele. (Personeller, Satışlar, Satış Detayları)
SELECT S.SatisTarihi,SUM(SD.Miktar * SD.BirimFiyati) TOPLAMTUTAR FROM Personeller P INNER JOIN Satislar S ON S.PersonelID = P.PersonelID
INNER JOIN [Satis Detaylari] SD ON SD.SatisID = S.SatisID
WHERE P.Adi LIKE '%a%' AND S.SatisID > 10500
GROUP BY S.SatisTarihi
- INNER JOIN'de eşleşen kayıtlar getiriliyordu. OUTER JOIN'de ise eşleşmeyen kayıtlarda getirilmektedir.
- JOIN ifadesinin solundaki tablodan tüm kayıtları getirir. Sağındaki tablodan eşleşenleri yan yana eşleşmeyenleri null olarak getirir.
SELECT * FROM OYUNCULAR O LEFT OUTER JOIN FİLMLER F ON F.FILMID = O.FILMID
SELECT * FROM FİLMLER O LEFT OUTER JOIN OYUNCULAR F ON F.FILMID = O.FILMID
-VEYA
SELECT * FROM OYUNCULAR O LEFT JOIN FİLMLER F ON F.FILMID = O.FILMID
SELECT * FROM FİLMLER O LEFT JOIN OYUNCULAR F ON F.FILMID = O.FILMID
- JOIN'in sağındaki tablonun tamamını getirecek, Solundakinden eşleşenleri aynı satırda eşleşmeyenleri de null olarak getirecek
SELECT * FROM OYUNCULAR O RIGHT OUTER JOIN FİLMLER F ON F.FILMID = O.FILMID
SELECT * FROM FİLMLER O RIGHT OUTER JOIN OYUNCULAR F ON F.FILMID = O.FILMID
-- VEYA
SELECT * FROM OYUNCULAR O RIGHT JOIN FİLMLER F ON F.FILMID = O.FILMID
- Joinin iki tarafındaki tablolardan eşleşen eşleşmeyen hepsini getirir.
SELECT * FROM OYUNCULAR O FULL OUTER JOIN FİLMLER F ON F.FILMID = O.FILMID
- VEYA
SELECT * FROM OYUNCULAR O FULL JOIN FİLMLER F ON F.FILMID = O.FILMID
- İki tablo arasında kartezyen çarpımı yapar. Kartezyen çarpımıyla birleştirir. İki küme arasında elemanları tek tek birbirleriyle eşleştirme işlemine kartezyen işlemi deriz.
- CROSS JOIN kullanarak iki tabloyu birleştirirsek eğer elde edilen sonuç iki tablonun eleman sayılarının çarpımları kadardır.
- WHERE ile şart uygulayamayız.
SELECT COUNT(*) FROM Personeller
SELECT COUNT(*) FROM Bolge
SELECT P.Adi,B.BolgeID FROM Personeller P CROSS JOIN BOLGE B
- SELECT ... -> Veritabanımızdaki tabloları elde etmemizi sağlayan komuttur.
- INSERT ... -> Veritabanımızdaki herhangi bir tabloya veri eklememizi sağlayan komuttur.
- UPDATE ... -> Veritabanımızdaki herhangi bir tablomuzda bulunan herhangi bir veriyi güncellememizi sağlayan komuttur.
- DELETE ... -> Veritabanımızdaki herhangi bir tablomuzda bulunan veriyi silmemizi sağlayan komuttur.
SELECT * FROM Personeller
INSERT [TABLO ADI](KOLONLAR) VALUES(DEĞERLER)
INSERT Personeller(Adi,SoyAdi) VALUES ('MUSA','UYUMAZ')
INSERT PERSONELLER VALUES('UYUMAZ','MUSA','YAZILIM VE VERİTABANI UZMANI','YM', '14.02.1999',GETDATE(),'ESKİŞEHİR','İÇ ANADOLU','26600','TÜRKİYE','02221111111',NULL,NULL,NULL,NULL,NULL)
- INTO Komutu İle Yazılabilir
INSERT INTO Personeller(Adi,SoyAdi) VALUES ('MUSA','UYUMAZ')
- Kolonun kabul ettiği veri tipi ve karakter uzunluğunda kayıt yapılmalıdır.
- NOT NULL olan kolonlar boş bırakılmayacaklarından dolayı mutlaka değer gönderilmelidir.
INSERT Personeller(Unvan,UnvanEki) VALUES ('a','b')
- Otomatik artan(identity) kolonlara değer gönderilmez.
- Tablodaki seçilen yahut bütün kolonlara değer gönderileceği belirtilip, gönderilmezse hata verecektir
INSERT Personeller(Adi,SoyAdi) VALUES ('MUSA')
INSERT Personeller VALUES ('MUSA','UYUMAZ')
INSERT Musteriler(MusteriAdi,Adres) VALUES('HİLMİ','ÇORUM')
INSERT Musteriler(MusteriAdi,Adres) VALUES('NECATİ','ÇANKIRI')
INSERT Musteriler(MusteriAdi,Adres) VALUES('RIFKI','YOZGAT')
INSERT Musteriler(MusteriAdi,Adres) VALUES('HİLMİ','ÇORUM'),
('HİLMİ','ÇORUM'),
('HİLMİ','ÇORUM')
INSERT ORNEKPERSONELLER SELECT Adi,SoyAdi FROM Personeller
- Burada dikkat etmeniz gereken nokta; SELECT sorgusunda dönen kolon sayısı ile INSERT işlemi yapılacak tablonun kolon sayısı birbirne eşit olması gerekmektedir. Aynı zamanda kolon özelliklerine de dikkat edilmelidir.
SELECT Adi, SoyAdi, Ulke INTO ORNEKPERSONELLER2 FROM Personeller
- Bu yöntemle primary key ve foreign keyler oluşturulamazlar.
- UPDATE [TABLO ADI] SET [KOLON ADI] = DEĞER
UPDATE ORNEKPERSONELLER SET ADI = 'MEHMET'
UPDATE ORNEKPERSONELLER SET ADI = 'MEHMET' WHERE ADI= 'NANCY'
UPDATE ORNEKPERSONELLER SET ADI = 'AYŞE' WHERE SOYADI = 'Davolio'
UPDATE Urunler SET UrunAdi = K.KategoriAdi FROM Urunler U INNER JOIN Kategoriler K ON U.KategoriID = K.KategoriID
UPDATE Urunler SET UrunAdi = (SELECT UrunAdi FROM Personeller WHERE PersonelID = 3)
UPDATE TOP(30) Urunler SET UrunAdi = 'x'
- DELETE FROM [TABLO ADI]
DELETE FROM Urunler
- [DELETE Sorgusuna WHERE Şartı Yazmak]
DELETE FROM Urunler WHERE KategoriID < 3
- DELETE sorgusuyla tablo içerisindeki verileri silmeniz identity kolonunu sıfırlamayacaktır. Silme işleminden sonra ilk eklenen veride kalınığı yerden id değeri verilecektir.
- Hem identity değerini sıfırlamak hem de verileri temizlemek istiyorsak eğer TRUNCATE komutunu kullanırız
- Birden fazla SELECT sorgusu sonucunu tek seferde alt alta göstermemizi sağlar.
SELECT Adi,SoyAdi FROM Personeller
SELECT MusteriAdi,MusteriUnvani FROM Musteriler
SELECT Adi,SoyAdi FROM Personeller
UNION
SELECT MusteriAdi,MusteriUnvani FROM Musteriler
- 2'den Fazla
SELECT Adi,SoyAdi FROM Personeller
UNION
SELECT MusteriAdi,MusteriUnvani FROM Musteriler
UNION
SELECT SevkAdi,SevkAdresi FROM Satislar
-
JOIN'ler yan yana, UNION alt alta tabloları birleştirir. JOIN'lerde belirli(ilişkisel) bir kolon üzerinden birleştirme yapılırken, UNION'da böyle bir durum yoktur.
-
Dikkat etmemiz gereken koşullar;
- UNION sorgusunun sonucunda oluşan tablonun kolon isimleri, üstteki sorgunun kolon isimlerinden oluşturulur.
- Üstteki sorgudan kaç kolon çekilmişse alttaki sorgudan da o kadar çekilmek zorundadır.
- Üsteki sorgudan çekilen kolonların tipleriyle, alttaki sorgudan çekilen kolonların tipleri uyumlu olmalıdır.
- UNION tekrarlı kayıtları getirmez.
-
UNION'da kullanılan tablolara kolon eklenebilir. Dikkat etmemiz gereken nokta, yukarıdaki kurallar çerçevesinde aşağıyada yukarıyada aynı sayıda kolonların eklenmesi gerekmektedir.
SELECT Adi,SoyAdi, 'Personel' FROM Personeller
UNION
SELECT MusteriAdi,MusteriUnvani, 'Müşteri' FROM Musteriler
- UNION tekrarlı kayıtları getirmez. Tekrarlı kayıtları getirmek için UNION ALL komutu kullanılmalıdır.
SELECT Adi,SoyAdi FROM Personeller
UNION ALL
SELECT Adi,SoyAdi FROM Personeller
- GROUP BY ile gruplanmış veri kümesinde ara toplam alınmasını sağlar.
SELECT SatisID,UrunID,SUM(Miktar) FROM [Satis Detaylari]
GROUP BY SatisID,UrunID WITH ROLLUP
SELECT KategoriID,UrunID,SUM(TedarikciID) FROM Urunler GROUP BY KategoriID,UrunID WITH ROLLUP
- [Having Şartıyla Beraber WITH ROLLUP]
SELECT SatisID,UrunID,SUM(Miktar) FROM [Satis Detaylari]
GROUP BY SatisID,UrunID WITH ROLLUP HAVING SUM(Miktar) > 100
- GROUP BY ile gruplanmış veri kümesinde teker teker toplam alınmasını sağlar.
SELECT SatisID,UrunID,SUM(Miktar) FROM [Satis Detaylari]
GROUP BY SatisID,UrunID WITH CUBE
SELECT KategoriID,UrunID,SUM(TedarikciID) FROM Urunler GROUP BY KategoriID,UrunID WITH CUBE
- [Having Şartıyla Beraber WITH ROLLUP]
SELECT SatisID,UrunID,SUM(Miktar) FROM [Satis Detaylari]
GROUP BY SatisID,UrunID WITH CUBE HAVING SUM(Miktar) > 100
-
Sorgularda şart kalıbı olarak kullanırız.
-
Personellerimizin isim ve soyisimlerinin yanında; UnvanEki 'Mr.' ise 'Erkek', 'Ms.' ise 'Kadın' yazsın.
SELECT Adi,SoyAdi,UnvanEki FROM Personeller
SELECT Adi,SoyAdi,
CASE
WHEN UnvanEki = 'Mrs.' OR UnvanEki = 'Ms.' THEN 'KADIN'
WHEN UnvanEki = 'Mr.' THEN 'ERKEK'
ELSE UnvanEki
END
FROM Personeller
- Eğer ürünün birim fiyatı 0 - 50 arası ise 'Çin Malı' 50 - 100 arası ise 'Ucuz', 100 - 200 arası ise 'Normal' ve 200'den fazla ise 'Pahalı' yazsın.
SELECT UrunID,BirimFiyati FROM Urunler
SELECT UrunID,
CASE
WHEN BirimFiyati BETWEEN 0 AND 50 THEN 'Çin Malı'
WHEN BirimFiyati BETWEEN 50 AND 100 THEN 'Ucuz'
WHEN BirimFiyati BETWEEN 100 AND 200 THEN 'Normal'
WHEN BirimFiyati> 200 THEN 'Pahalı'
ELSE 'BELİRSİZ'
END
FROM Urunler
-
TOP komutunu kullanırken kullanıdığımız bir komuttur.
-
Bağıl değerlendirme yapmamızı sağlar. Yani bir yarışma düşünün ilk 3'e ödül vereceksiniz ama 3.y'le aynı puan alan diğer yarışmacıları da istiyorsanız eğer bu komutu kullanabilirsiniz.
-
WITH TIES hangi kolona uygun bir şekilde işlem yapacaktır. Hangisinde devamlılık söz konusuysa o kolonu belirtmemiz gerekmektedir. Bunu da ORDER BY ile yaparız.
SELECT * FROM [Satis Detaylari]
SELECT TOP 6 WITH TIES * FROM [Satis Detaylari] ORDER BY SatisID
-
Herhangi bir sorguda parametrik özellik kazandırmamızı sağlayan bir komuttur.
-
İleride göreceğimiz Stored Procedure, View gibi yapıların kaydedilebilir olması iken WITH Komutu kaydedilemeyen keza biz direkt fiziksel olarak kaydetmediğimiz sürece çalıştırdığımızda herhangi bir veritabanının yapısına kaydedilmeyen yapıdadır. Yani anlık olarak kullanıp işimizi gören bir komuttur.
-
Kompleks sorguların yazılma sürecinde daha da komplekse gidiyorsa eğer WITH komutuyla biz mevcut sorguyu parametrik hale getirip daha okunabilir ve daha da işimizi kolaylaştırabilir bir yapı kazandırmayı hedefliyoruz.
WITH PERSONELSATIS(ID,ADI,SOYADI,SATISID)
AS
(
SELECT P.PersonelID,P.Adi,P.SoyAdi,S.SatisID FROM Personeller P INNER JOIN Satislar S ON P.PersonelID = S.PersonelID
)
SELECT * FROM PERSONELSATIS PS INNER JOIN [Satis Detaylari] SD ON SD.SatisID = PS.SATISID
- Herhangi bir sorgunun çıktısı başka bir sorgunun girdisi olabilir.
- Herhangi bir sorgudan elde ettiğimiz veriyi biz başka bir sorguda kullanabilmekteyiz.
SELECT * FROM Personeller P INNER JOIN Satislar S ON P.PersonelID = S.PersonelID WHERE Adi = 'NANCY'
SELECT SatisID,SatisTarihi FROM Satislar WHERE PersonelID = (SELECT PersonelID FROM Personeller WHERE Adi = 'NANCY')
SELECT Adi FROM Personeller WHERE Adi = (SELECT Adi FROM Personeller WHERE UnvanEki = 'Dr.')
- Önceden fiziksel bir tablonun oluşturulmuş olması gerekmektedir.
- Harici kaynaktaki kolonlarımızın tipleri ve kaç tane olduğu önemlidir.
BULK INSERT Kisiler
FROM 'D:\Kisiler.txt'
WITH
(
FIELDTERMINATOR = '\t',
ROWTERMINATOR = '\n'
)
- Veritabanındaki herhangi bir tablomuzun tüm verilerini silmemizi sağlayan ve bu işlemi yaparkende IDENTITY kolonunu sıfırlamamızı sağlayan bir komuttur.
- DELETE ile de tablodaki tüm verileri silebiliyoruz ama TRUNCATE'ten tek farkı ilgili IDENTITY kolonunu sıfırlamamakta sadece verileri silip IDENTITY kolonunu kaldığı yerde bırakmaktadır. Haliyle herhangi bir veri eklendiği vakit IDENTITY nerede kaldıysa oradan devam etmektedir.
SELECT * INTO PERSONELLERX FROM PERSONELLER
DELETE FROM PERSONELLERX
TRUNCATE TABLE PERSONELLERX
- İlgili veritabanı içerisinde yapılan en son INSERT işleminin identity değerini bizlere getiren bir komuttur.
- INSERT işleminden sonra direkt @@IDENTITY komutunu çağırmaktayız.
INSERT Kategoriler(KategoriAdi,Tanimi) VALUES('X','X Kategorisi')
SELECT @@IDENTITY
INSERT PERSONELLERX(Adi,SoyAdi) VALUES('Ela','Elif')
SELECT @@IDENTITY
- Biz yapmış olduğumuz işlem neticesinde kaç tane elemanın etkilendiğini bulabiliyoruz.
DELETE FROM PERSONELLERX WHERE SoyAdi = 'Gençay'
SELECT @@ROWCOUNT
SELECT * FROM Personeller
SELECT @@ROWCOUNT
INSERT PERSONELLERX(Adi,SoyAdi) VALUES('Gençay','Yıldız'),
('Ahmet','Uslu'),
('Aslı','Güngör')
SELECT @@ROWCOUNT
- Bir tabloda bulunan identity değerinin nereden devam edeceğini ayarlayabiliyoruz.
- Burada ilgili tabloda bulundan identity değerlerinden büyük bir değer girmeliyiz.
DBCC Checkident(PERSONELLERX,reseed,27)
- NULL dediğimiz değerler değersiz anlamına gelen değerlerdir. Yani bir değerin olmadığını ifade ederler.
SELECT MusteriAdi,Bolge FROM Musteriler
SELECT MusteriAdi,
CASE
WHEN BOLGE IS NULL THEN 'BÖLGE BİLİNMİYOR'
ELSE BOLGE
END
FROM Musteriler
- Verdiğimiz kolondaki NULL değerlere verdiğimiz ikinci parametredeki değere göre değiştirecektir.
SELECT MusteriAdi, COALESCE(Bolge,'BÖLGE BİLİNMİYOR') FROM Musteriler
- COALESCE Fonksiyonunda olduğu gibi eğer ki null olmayan değerler varsa onları aynı şekil bırakıyor. NULL değerlerin yerine de parametrede belirtilen değeri veriyor.
SELECT MusteriAdi,ISNULL(Bolge,'Bölge Bilinmiyor') FROM Musteriler
-
Fonksiyona verilen kolon,Birinci parametredeki değer eğer ikinci parametrede verilen değere eşit ise o kolonu NULL olarak getirir.
-
Eğer ki parametredeki değerler eşit değilse bize birinci parametredeki değeri döndürür.
-
NULL değerler raporlamada yani istatistiksel matematiksel işlemlerde sonucu saptırabilmekte ve beklediğimiz sonuçları alamamaktayız. Nihayetinde NULL değerleri ya hükmedebilmeli değiştirmeli ya da NULL değerleri hesaplamadan çıkarmalıyız.
-
NULL değerleri serbest bırakmayın kendi amacınız doğrultusunda ister değer atayacaksınız ister farklı bir ayraç atayacaksınız ama NULL olarak bırakmayacaksınız. Raporlamada her zaman NULL değerlere dikkat etmek gerekir.
SELECT NULLIF(2,2)
SELECT HedefStokDuzeyi FROM Urunler
SELECT AVG(HedefStokDuzeyi) FROM Urunler
- Hedef stok düzeyi 0 olmayan ürünlerin ortalaması nedir?
SELECT AVG(HedefStokDuzeyi) FROM Urunler WHERE HedefStokDuzeyi <> 0
SELECT AVG(NULLIF(HedefStokDuzeyi,0)) FROM Urunler
- Çalıştığınız veritabanının içindeki tablolara erişmek istiyorsanız aşağıdaki sorguları kullanabilirsiniz.
SELECT * FROM SYS.TABLES
- ya da
SELECT * FROM SYSOBJECTS WHERE XTYPE='U'
- Eğer ki 1 değerini döndürüyorsa ilgili tablo içinde primary key var olduğunu göstermektedir. Yok eğer 0 gösteriyorsa demek ki ilgili tablo içinde herhangi bir primary key yok demektir.
SELECT OBJECTPROPERTY(OBJECT_ID('PERSONELLER'),'TABLEHASPRIMARYKEY')
- T-SQL'de veritabanı nesneleri yaratmamızı sağlayan ve bu nesneler üzerinde değişiklikler yapmamızı ve silmemizi sağlayan yapılar bu başlık altında simgelenmektedir.
-
Veritabanı nesnesi yaratmamızı sağlar (Database, Table, View, Stored Procedure, Trigger, vs.)
-
Prototipi
-
CREATE [NESNE] [NESNENİN ADI]
CREATE DATABASE OrnekVeritabani
- Bu şekilde bir kullanım varsayılan ayarlarda veritabanı oluşturacaktır.
CREATE DATABASE OrnekVeritabani
ON
(
NAME = 'GG',
FILENAME = 'D:\GG.mdf',
SIZE = 5,
FILEGROWTH = 3
)
- NAME : Oluşturulacak veritabanının fiziksel ismini belirtiyoruz.
- FILENAME : Oluşturulacak veritabanının dosyasının fiziksel dizinini belirtiyoruz.
- SIZE : Veritabanının başlangıç boyutunu MB cinsinden ayarlıyoruz.
- FILEGROWTH : Veritabanın boyutu, başlangıç boyutunu geçtiği durumda boyutun ne kadar artması gerektiğini MB cinsinden belirtiyoruz.
CREATE DATABASE OrnekVeritabani
ON
(
NAME = 'GG',
FILENAME = 'D:\GG.mdf',
SIZE = 5,
FILEGROWTH = 3
)
LOG
ON
(
NAME = 'GG_LOG',
FILENAME = 'D:\GG.ldf',
SIZE = 5,
FILEGROWTH = 3
)
USE ORNEKVERITABANI
CREATE TABLE ORNEKTABLO
(
KOLON1 INT,
KOLON2 NVARCHAR(MAX),
KOLON3 MONEY
)
- Eğer kolon adlarında boşluk varsa köşeli parantez([]) ile belirtilmelidir.
CREATE TABLE ORNEKTABLO2
(
[KOLON 1] INT,
[KOLON 2] NVARCHAR(MAX),
[KOLON 3] MONEY
)
CREATE TABLE ORNEKTABLO3
(
ID INT PRIMARY KEY IDENTITY(1,1),
[KOLON 2] NVARCHAR(MAX),
[KOLON 3] MONEY
)
-
CREATE ile yaratılan veritabanı nesnelerinde değişiklik yahut güncelleme işlemi yapmamızı sağlar.
-
Prototip
-
ALTER [NESNE] [NESNENİN ADI]
-
(Yapıya Göre İşlemler)
ALTER DATABASE ORNEKVERITABANI
MODIFY FILE
(
NAME = 'ORNEKVERITABANI',
SIZE = 20
)
ALTER TABLE ORNEKTABLO
ADD KOLON4 NVARCHAR(MAX)
ALTER TABLE ORNEKTABLO
ALTER COLUMN KOLON4 INT
ALTER TABLE ORNEKTABLO
DROP COLUMN KOLON4
ALTER TABLE ORNEKTABLO
ADD CONSTRAINT ORNEKCONSTRAINT DEFAULT 'BOŞ' FOR KOLON2
ALTER TABLE ORNEKTABLO
DROP CONSTRAINT ORNEKCONSTRAINT
SP_RENAME 'ORNEKTABLO', 'ORNEKTABLOYENI'
SP_RENAME 'ORNEKTABLOYENI.KOLON1' ,'KOLON1453','COLUMN'
-- CREATE ile oluşturulan veri tabanı nesnelerini silmemize yarar.
-- DROP [NESNE] [NESNE ADI]
DROP TABLE ORNEKTABLOYENI
DROP DATABASE ORNEKVERITABANI
-
Constraintler sayesinde tablolar üzerinde istediğimiz şartlar ve durumlara göre kısıtlamalar yapabiliyoruz.
-
Bir tabloya özel şart durum ya da herhangi bir varsayılan değeri Constraint'imizi oluşturduğumuz zaman bu constraint ilgili tabloya fiziksel olarak oluşturulacaktır.
-
CONSTRAINT Türleri;
-
- DEFAULT CONSTRAINT
-
- CHECK CONSTRAINT
-
- PRIMARY KEY CONSTRAINT
-
- UNIQUE CONSTRAINT
-
- FOREIGN KEY CONSTRAINT
-
- DEFAULT CONSTRAINT sayesinde kolona bir değer girilmediği taktirde varsayılan olarak ne girilmesi gerektiğini belirtebiliyoruz.
- Herhangi bir tablo içerisindeki herhangi bir kolonun boş geçilmesi durumunda ilgili kolona girilecek olan varsayılan değerin ne olması gerektiğini DEFAULT CONSTRAINT sayesinde belirtebiliyoruz.
- ADD CONSTRAINT [CONSTRAINT ADI] DEFAULT 'VARSAYILAN DEĞER' FOR [KOLON ADI]
CREATE TABLE ORNEKTABLO
(
ID INT PRIMARY KEY IDENTITY(1,1),
KOLON1 NVARCHAR(MAX),
KOLON2 INT
)
ALTER TABLE ORNEKTABLO
ADD CONSTRAINT KOLON1CONSTRAINT DEFAULT 'BOŞ' FOR KOLON1
ALTER TABLE ORNEKTABLO
ADD CONSTRAINT KOLON2CONSTRAINT DEFAULT -1 FOR KOLON2
INSERT ORNEKTABLO(KOLON2) VALUES(0)
INSERT ORNEKTABLO(KOLON1) VALUES('ÖRNEK BİR DEĞER')
SELECT * FROM ORNEKTABLO
-
Bir kolona girilecek olan verinin belirli bir şarta uymasını zorunlu tutar.
-
Herhangi bir kolona girilecek olan verinin önceden belirttiğim bir şarta göre CHECK/kontrol edilip CHECK sonucunda olumlu ya da olumsuz olma durumuna göre ilgili kolona ilgili verinin kaydedilmesini inceleyen constraint'tir.
-
Genel Yapısı;
-
ADD CONSTRAINT [CONSTRAINT ADI] CHECK (ŞART)
ALTER TABLE ORNEKTABLO
ADD CONSTRAINT KOLON2KONTROL CHECK ((KOLON2 * 5) % 2 = 0)
-
CHECK constraint oluşturulmadan önce ilgili tabloda şarta aykırı değerler varsa eğer constraint oluşturulmayacaktır! ! !
-
Ancak önceki kayıtları görmezden gelip yinede CHECK constrainti uygulamak istiyorsak WITH NOCHECK komutu kullanılmalıdır.
- Şu ana kadar kayıtları görmezden gelip, CHECK constrainti uygulattırır.
ALTER TABLE ORNEKTABLO
WITH NOCHECK ADD CONSTRAINT KOLON2KONTROL CHECK((KOLON2 * 5) % 2 = 0)
-
PRIMARY KEY Constraint ile; o kolona eklenen PRIMARY KEY ile, başka tablolarda FOREIGN KEY oluşturarak ilişki kurmamız mümkün olur. Bunun yanında o kolonun taşıdığı verinin tekil olacağı da garanti edilmiş olur. PRIMARY KEY Constraint ile ayrıca CLUSTERED INDEX oluşturulmuş da olur.
-
Genel Yapısı
-
ADD CONSTRAINT [CONSTRAINT ADI] PRIMARY KEY [KOLON ADI]
-
DİKKAT !!!
-
PRIMARY KEY Constraint kullanılan kolon PRIMARY KEY özelliğine sahip olmamalıdır.
-
Kullanacağımız tablonun içerisinde ise başka PRIMARY KEY kolonu olmamalıdır. Çünkü bir tabloda sadece bir tane PRIMARY KEY kolon bulunabilir.
ALTER TABLE ORNEKTABLO
ADD CONSTRAINT PRIMARYID PRIMARY KEY (ID)
-
UNIQUE CONSTRAINT'in tek amacı, belirttiğimiz kolondaki değerlerin tekil olmasını sağlamaktadır.
-
Birden fazla tekrarlı kaydın girmesini engellemektedir.
-
Genel Yapısı;
-
ADD CONSTRAINT [CONSTRAINT ADI] UNIQUE (KOLON ADI)
ALTER TABLE ORNEKTABLO
ADD CONSTRAINT ORNEKTABLOUNIQUE UNIQUE (KOLON2)
- KOLON2 kolonuna UNIQUE Constraint verilerek tekil hale getirilmiştir. Bundan sonra iki tane aynı veriden kayıt yapılamamaktadır.
-
Tabloların kolonları arasında ilişki kurmamızı sağlar. Bu ilişki neticesinde FOREIGN KEY olan kolondaki karşılığının boşa düşmemesi için PRIMARY KEY kolonu olan tablodan veri silinmesini güncellenmesini engeller
-
Genel Yapısı;
-
ADD CONSTRAINT [CONSTRAINT ADI] FOREIGN KEY (KOLON ADI) REFERENCES [2.TABLO ADI](2. TABLODAKİ KOLON ADI)
CREATE TABLE OGRENCILER
(
OGRENCIID INT PRIMARY KEY IDENTITY(1,1),
DERSID INT,
ADI NVARCHAR(MAX),
SOYADI NVARCHAR(MAX)
)
CREATE TABLE DERSLER
(
DERSID INT PRIMARY KEY IDENTITY(1,1),
DERSADI NVARCHAR(MAX)
)
ALTER TABLE OGRENCILER
ADD CONSTRAINT FOREIGKEYOGRENCIDERS FOREIGN KEY (DERSID) REFERENCES DERSLER(DERSID)
-
Şu durumda DELETE UPDATE işlemlerinden ilişkili kolondaki veriler etkilenmez.
-
Davranışı değiştirmek için aşağıdaki komutlar kullanılır.
- CASCADE
- SET NULL
- SET DEFAULT
- Ana tablodaki kayıt silindiğinde ya da güncellendiğinde ilişkili kolondaki karşılığıda otomatik olarak silinir ya da güncellenir.
ALTER TABLE OGRENCILER
ADD CONSTRAINT FOREIGNKEYOGRENCIDERS FOREIGN KEY (DERSID) REFERENCES DERSLER(DERSID)
ON DELETE CASCADE
ON UPDATE CASCADE
- Ana tablodaki kayıt silindiğinde ya da güncellendiğinde ilişkili kolondaki karşılığıda NULL değer basılır.
ALTER TABLE OGRENCILER
ADD CONSTRAINT FOREIGNKEYOGRENCIDERS FOREIGN KEY (DERSID) REFERENCES DERSLER(DERSID)
ON DELETE SET NULL
ON UPDATE SET NULL
- Ana tablodaki kayıt silindiğinde ya da güncellendiğinde ilişkili kolondaki karşılığına o kolonun default değeri basılır. Bu default değer dediğimiz default tipte bir constraint'tir. Bunu kendimiz oluşturabiliriz.
ALTER TABLE OGRENCILER
ADD CONSTRAINT DEFAULTOGRENCILER DEFAULT -1 FOR DERSID
ALTER TABLE OGRENCILER
ADD CONSTRAINT FOREIGNKEYOGRENCIDERS FOREIGN KEY (DERSID) REFERENCES DERSLER(DERSID)
ON DELETE SET DEFAULT
ON UPDATE SET DEFAULT
- Bu ayarlar verilmediği taktirde NO ACTION özelliği geçerlidir.
-
DECLARE Keywordü ile değişken tanımlanır.
-
DECLARE Komutu TSQL'de değişken oluşturmamızı sağlayan bir komuttur.
-
Prototip;
-
DECLARE @DEGISKENADI DEGISKENTIP
DECLARE @X INT
DECLARE @Y NVARCHAR
DECLARE @Z MONEY
DECLARE @X INT, @Z NVARCHAR, @Y BIT
DECLARE @YAS INT = 3
-
Önceden tanımlanmış ya da oluşturulmuş bir değişkenin değerine müdahale etmek istiyorsak SET komutunu kullanmalıyız.
-
SET komutu C# programlama dilinde bir property'nin dışarıdan verilen değeri yakaladığı bloktu. TSQL'de de aynı mantık değişkene dışarıdan verilen değer varsa SET ile yakalayacağız.
DECLARE @YAS INT = 3
DECLARE @X INT
-- SET
SET @X = 125
DECLARE @TARIH DATETIME = GETDATE()
SET @TARIH = GETDATE()
-
Assign operatörünün(=) solundaysa eğer değişkenin referansı verilen değeri ata anlamına gelmektedir. Değişkenin referansı Yani Assign operatörünün(=) solundaysa o bize değişkenin değerini getirmez ama herhangi bir değişkenin direkt ismini çağırıyorsak direkt o değişkenin değerini getirir
-
SELECT komutu bir tablo oluşturur.
DECLARE @X INT
SET @X = 3 --X Değişkenine 3 değerini atadık
SELECT @X
PRINT @X
DECLARE @ADI NVARCHAR(MAX), @SOYADI NVARCHAR(MAX)
SELECT @ADI=Adi, @SOYADI=SoyAdi FROM Personeller WHERE PersonelID = 1
SELECT @ADI,@SOYADI
- Sorgu sonucu gelen satır sayısı bir adet olmalıdır.
- Kolonlardaki verilerin tipleri ne ise o verileri temsil edecek değişkenlerin tipleri de benzer olmalıdır.
-
GO komutu, eğer ki bir pencerede birden fazla işlem yapıyorsak ve bu işlemler birbirlerinden bağımsız ise bu yapıların birbirlerinden bağımsız olduğunu derleyiciyi de göstermek istiyorsak bu komutu kullanıyoruz.
-
Birbirlerinden bağımsız olan komutları bağımsızlığını derleyiciye GO komutu aracılığıyla göstermiş oluyoruz.
-
GO işlemi biten komutları birbirleriden ayırmaktadır.
CREATE DATABASE ORNEKDATABASE
GO
USE ORNEKDATABASE
GO
CREATE TABLE ORNEKTABLO
(
ID INT PRIMARY KEY IDENTITY(1,1),
KOLON1 NVARCHAR(MAX),
KOLON2 NVARCHAR(MAX)
)
-
IF dediğimiz yapıda koşulumuzun sonuç olarak TRUE ya da FALSE yani TSQL'de BIT olarak dönmesi gerekmektedir.
-
IF ELSE yapısı içerisinde birden fazla komut kullanacaksak eğer scope anlamına gelen BEGIN END yapısı dediğimiz yapıları kullanırız.
-
=
: Eşitse C# == -
<>
: Eşit Değilse C# != -
>
: Büyükse -
<
: Küçükse
DECLARE @ISIM NVARCHAR(MAX)
SET @ISIM = 'MUSA'
IF @ISIM = 'MUSA'
PRINT 'EVET'
ELSE
PRINT 'HAYIR'
DECLARE @SAYI1 INT = 3
DECLARE @SAYI2 INT = 5
IF @SAYI1 < @SAYI2
BEGIN
PRINT 'EVET SAYI1 SAYI2''DEN KÜÇÜKTÜR.'
SELECT @SAYI1 [SAYI 1],@SAYI2 [SAYI 2]
END
ELSE
BEGIN
PRINT 'HAYIR SAYI1 SAYI2''DEN KÜÇÜK DEĞİLDİR.'
SELECT @SAYI1 [SAYI 1],@SAYI2 [SAYI 2]
END
- Örnek 1
- Müşteriler tablosunda Amerikalı (USA) müşteri var mı?
SELECT * FROM Musteriler WHERE Ulke = 'USA'
IF @@ROWCOUNT > 0
PRINT 'EVET VAR'
ELSE
PRINT 'HAYIR YOK'
-
@@ROWCOUNT Yapılan işlemden etkilenen satır sayısını getirir.
-
Örnek 2
-
Adı 'MUSA' soyadı 'UYUMAZ' olan personel var mı? Varsa Evet desin Yoksa kaydetsin.
DECLARE @ADI NVARCHAR(MAX) = 'MUSA', @SOYADI NVARCHAR(MAX) = 'UYUMAZ'
SELECT * FROM Personeller WHERE Adi = @ADI AND SoyAdi = @SOYADI
IF @@ROWCOUNT > 0
PRINT 'EVET VAR.'
ELSE
BEGIN
PRINT 'HAYIR YOK...'
INSERT Personeller([SoyAdi], [Adi]) VALUES (@SOYADI,@ADI)
END
DECLARE @ADI NVARCHAR(MAX) = 'MUSA'
DECLARE @YAS INT = 24
IF @ADI = 'MAHMUT'
PRINT 'EVET MAHMUT'
ELSE IF @YAS > 23
PRINT 'YAŞI 23''TEN BÜYÜK'
ELSE IF 3 > 5
BEGIN
PRINT ''
END
ELSE IF 1 = 1
PRINT 'EŞİT'
ELSE
PRINT 'ABC'
- Herhangi bir sorgu neticesinde gelen tablonun boş mu dolu mu olduğunu öğrenmemizi sağlayan bir fonksiyondur.
IF EXISTS(SELECT * FROM Personeller)
PRINT 'DOLU'
ELSE
PRINT 'BOŞ'
- Prototip;
- WHILE ŞART KOMUT
DECLARE @SAYAC INT = 0
WHILE @SAYAC < 100
BEGIN
PRINT @SAYAC
SET @SAYAC = @SAYAC + 1
END
- Herhangi bir döngü içerisinde compiler/derleyici BREAK komutunu görürse bulunduğu yapıyı terk eder.
DECLARE @SAYAC INT = 0
WHILE @SAYAC < 1000
BEGIN
PRINT @SAYAC
SET @SAYAC = @SAYAC + 1
IF @SAYAC % 5 = 0
BREAK
END
- CONTINUE komutu derleyici tarafından karşılaşıldığı zaman Continue komutundan sonraki komutlar işlenmemektedir.
DECLARE @SAYAC INT = 0
WHILE @SAYAC < 100
BEGIN
SET @SAYAC = @SAYAC + 1
IF @SAYAC % 5 = 0
CONTINUE
PRINT @SAYAC
END
WHILE @SAYAC < 1000
BEGIN
IF @SAYAC % 5 = 0
BEGIN
SET @SAYAC = @SAYAC + 1
CONTINUE
END
PRINT @SAYAC
SET @SAYAC = @SAYAC + 1
END
-- Geçici Tablolar - Temporary Tables
-
Genellikle bir SQL Server üzerinde farklı lokasyonlarda birden fazla kişinin çalıştığı durumlarda ya da verilerin test amaçlı geçici bir yerlerde tutulması, işlenmesi amacıyla kullanılan yapılardır.
-
Bilinen tablo yapısının aynısını sağlarlar. Tek farkları fiziksel olarak oluşmazlar. Sadece bellekte geçici olarak oluşturulurlar.
-
SELECT INSERT UPDATE ve DELETE işlemleri yapabilir. İlişki kurabilir.
-
Sunucu kapatıldığında ya da oturum sahibi oturumu kapattığında bellekten silinirler.
-
Fiziksel olarak tablolarımızda bir değişiklik olmasını istemiyorsak verilerimizde oynama yapılmasını test edilme sürecinde herhangi bir değişikliğe mahal verilmesini istemiyorsak geçici tabloları kullanıyoruz.
-
Yapılan hiçbir işlem fiziksel tabloya yansıtılmamaktadır.
- Elimizdeki tablolar üzerinde test yapacaksak ve bu test ilgili tablonun fiziksel halini değiştirme ihtimali varsa ya da veri kaybı söz konusuysa ya da değişikliği mahal bıramak istemiyorsak geçici tabloları kullanacağız ya da bu tablonun bir kopyasını alacağız.
SELECT * INTO GECICIPERSONELLER FROM Personeller
- Bu şekilde bir kullanımda sadece PRIMARY KEY ve FOREIGN KEY constraint'ker oluşturulmazlar. Geri kalan herşey birebir fiziksel olarak oluşturulur.
SELECT * FROM GECICIPERSONELLER
- Geçici tablolarda yani bellek üzerine kopyalanmış tablolarda çalışabiliriz. Haliyle bu tablolar üzerinde yapmış olduğumuz tüm değişiklikler ilgili oturum/bilgisayar/SQL Server kapatıldığında bellekten silinecek ve fiziksel tabloya yansıtılmayacaktır.
SELECT * INTO #GECICIPERSONELLER FROM Personeller
SELECT * FROM #GECICIPERSONELLER
INSERT #GECICIPERSONELLER(Adi,SoyAdi) VALUES ('MUSA','UYUMAZ')
DELETE FROM #GECICIPERSONELLER WHERE PersonelID = 3
UPDATE #GECICIPERSONELLER SET Adi= 'GENÇAY', SoyAdi = 'YILDIZ' WHERE PersonelID = 5
-
Geçici tablo üzerinde her türlü işlem yapabiliyoruz.
-
#
ile oluşturulan tablo o an SQL Server'da oturum açmış kişinin sunucu belleğinde oluşur. -
Sadece oturum açan şahıs kullanabilir.
-
Eğer oturum açan şahıs SQL Server'dan disconnect olursa bu tablo bellekten silinir.
SELECT * INTO ##GECICIPERSONELLER2 FROM Personeller
SELECT * FROM ##GECICIPERSONELLER2
INSERT ##GECICIPERSONELLER2(Adi,SoyAdi) VALUES ('MUSA','UYUMAZ')
DELETE FROM ##GECICIPERSONELLER2 WHERE PersonelID = 3
UPDATE ##GECICIPERSONELLER2 SET Adi= 'GENÇAY', SoyAdi = 'YILDIZ' WHERE PersonelID = 5
-##
ile oluşturulan tablo o an SQL Server'da oturum açmış kişinin sunucu belleğinde oluşur.
-
Bu tabloyu oturum açan şahıs ve onun SQL Server'ına dışarıdan ulaşan 3. şahıslar kullanabilir.
-
Eğer oturum açan şahıs SQL Server'dan disconnect olursa bu tablo bellekten silinir.
-
Diğer bütün özellikleri
#
ile oluşturulan tablo ile aynıdır
-
INT VARCHAR vs. gibi bir veri tipidir.
-
Aldığı değer, rakamlar ve harflerden oluşan çok büyük bir sayıdır.
-
Bundan dolayı bu kolona aynı değerin birden fazla kez gelmesi neredeyse imkansızdır.
-
O yüzden tekil bir veri oluşturmak için kullanılır.
-
Genellikle biz bu türü yazmış olduğun bir sistemde kullanıcı kayıt yaptığı zaman ilgili kullanıcıdan mail onayı istiyorsak UNIQUEIDENTIFIER'la bir linki kullanıcıya göndeririz. O link o kullanıcıya özel olur kullanıcı linke tıkladığında ilgili UNIQUEIDENTIFIER'a özel kullanıcıyı kıyaslarız eğer öyle bir kullanıcı varsa o kullanıcıyı aktifleştiririz.
CREATE TABLE ORNEKTABLO2
(
ID INT PRIMARY KEY IDENTITY,
KOLON1 NVARCHAR(MAX),
KOLON2 NVARCHAR(MAX),
KOLON3 UNIQUEIDENTIFIER
)
- NEWID Fonksiyonu anlık olarak random yani rastgele bir şekilde UNIQUEIDENTIFIER tipinde veri üretmemizi sağlamakta
SELECT NEWID()
INSERT ORNEKTABLO2 VALUES('X','Y',NEWID())
SELECT * FROM ORNEKTABLO2
-
Genellikle karmaşık sorguların tek bir sorgu üzerinden çalıştırılabilmesidir.
-
Bu amaçla raporlama işlemlerinde kullanılabilirler.
-
Aynı zamanda güvenlik ihtiyacı olduğu durumlarda herhangi bir sorgunun 2. - 3. şahıslardan gizlenmesi amacıyla da kullanılırlar.
-
Herhangi bir sorgunun sonucunu tablo olarak ele alıp, ondan sorgu çekilebilmesini sağlarlar.
-
INSERT, UPDATE, DELETE yapabilirler. Bu işlemleri fiziksel tabloya yansıtırlar. *** Önemli
-
VIEW yapıları fiziksel olarak oluşturulan yapılardır. Yani veritabanında kaydedilmektedirler.
-
VIEW yapıları normal sorgulardan daha yavaş çalışırlar.
- Database elemanlarını CREATE komutuyla oluşturuyorduk. VIEW yapısıda bir database yapısı olduğu için CREATE komutu ile oluşturacağız.
CREATE VIEW VW_GOTUR
AS
SELECT P.Adi + ' ' + P.SoyAdi [ADI SOYADI], K.KategoriAdi [KATEGORİ ADI], COUNT(S.SatisID) [TOPLAM SATIŞ] FROM Personeller P
INNER JOIN Satislar S ON P.PersonelID = S.PersonelID
INNER JOIN [Satis Detaylari] SD ON S.SatisID = SD.SatisID
INNER JOIN Urunler U ON U.UrunID = SD.UrunID
INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID
GROUP BY P.Adi + ' ' + P.SoyAdi , K.KategoriAdi
SELECT * FROM VW_GOTUR
SELECT * FROM VW_GOTUR WHERE [ADI SOYADI] LIKE '%ROBERT%'
-
VIEW oluşturulurken kolonlara verilen aliaslar VIEW'den sorgu çekilirken kullanılır.
-
Bir yandan da VIEW'ın kullandığı gerçek tabloların kolon isimleri, VIEW içinde alias tanımlanarak gizlenilmiş olunur.
-
VIEW içinde ORDER BY kullanılmaz.
-
ORDER BY VIEW içinde değil VIEW çalışırken sorgu esnasında kullanılmalıdır.
SELECT * FROM VW_GOTUR ORDER BY [TOPLAM SATIŞ]
-
Yok eğer illaki VIEW içinde ORDER BY kullanacağım diyorsanız VIEW içinde TOP komutunu kullanmalısınız.
-
TOP komutu ORDER BY'ın kullanılmasını sağlamaktadır.
CREATE VIEW VW_GOTUR
AS
SELECT TOP 100 P.Adi + ' ' + P.SoyAdi [ADI SOYADI], K.KategoriAdi [KATEGORİ ADI], COUNT(S.SatisID) [TOPLAM SATIŞ] FROM Personeller P
INNER JOIN Satislar S ON P.PersonelID = S.PersonelID
INNER JOIN [Satis Detaylari] SD ON S.SatisID = SD.SatisID
INNER JOIN Urunler U ON U.UrunID = SD.UrunID
INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID
GROUP BY P.Adi + ' ' + P.SoyAdi , K.KategoriAdi ORDER BY [TOPLAM SATIŞ]
-
Bu durum çokta tavsiye edilen bir durum değildir.
-
VIEW üzerinde INSERT, DELETE ve UPDATE yapılabilir. Bu işlemler fiziksel tabloya yansıtılmaktadırlar.
CREATE VIEW ORNEKVIEWPERSONELLER
AS
SELECT Adi,SoyAdi,Unvan FROM Personeller
INSERT ORNEKVIEWPERSONELLER VALUES('MUSA','UYUMAZ','YZLM. VRTBN. UZMN')
UPDATE ORNEKVIEWPERSONELLER SET Adi = 'SERHAT' WHERE Adi = 'MUSA'
DELETE FROM ORNEKVIEWPERSONELLER WHERE Adi = 'SERHAT'
- Eğer yazdığımız VIEW'ın kaynak kodlarını, Object Explorer penceresinde VIEWS kategorisine sağ tıklayarak Design Modda açıp görüntülenmesini istemiyorsak WITH ENCRYPTION komutu ile VIEW'ı oluşturmalıyız.
- WITH ENCRYPTION işleminden sonra VIEW'i oluşturan kişide dahil kimse komutları göremez. Geri dönüş yoktur. Ancak VIEW'i oluşturan şahsın komutların yedeğini bulundurması gerekmektedir. Ya da WITH ENCRYPTION olmaksızın VIEW yapısını yeniden ALTER'lamalıyız.
- Bir dikkat etmemiz gereken nokta da WITH ENCRYPTION ifadesini AS keywordünden önce yazmalıyız.
CREATE VIEW ORNEKVIEWPERSONELLER
WITH ENCRYPTION
AS
SELECT Adi,SoyAdi,Unvan FROM Personeller
- Bu işlemi yaptıktan sonra Design Modu kapatılmıştır.
-
Eğer VIEW'in kullandığı esas fiziksel tabloların kolon isimleri bir şekilde değiştirilir, kolonları silinir ya da tablo yapısı bir şekilde değişikliğe uğrar ise VIEW'in çalışması artık mümkün olmayacaktır.
-
VIEW'in kullandığı tablolar ve kolonları bu tarz işlemler yapılabilmesi ihtimaline karşı koruma altına alınabilir.
-
Bu koruma WITH SCHEMABINDING ile VIEW CREATE ya da ALTER edilirken, VIEW'in kullandığı tablo SCHEMA adıyla birlikte verilmelidir. Örneğin, DBO(DATABASE OWNER) bir şema adıdır. Şemalar C#'taki NAMESPACE'ler gibi düşünülebilir.
-
WITH SCHEMABINDING komutuda AS keywordünden önce yazılmalıdır.
CREATE TABLE ORNEKTABLO
(
ID INT PRIMARY KEY IDENTITY,
KOLON1 NVARCHAR(MAX)
)
CREATE VIEW ORNEKVIEW
WITH SCHEMABINDING
AS
SELECT ID, KOLON1 FROM DBO.ORNEKTABLO
ALTER TABLE ORNEKTABLO
ALTER COLUMN KOLON1 INT
- VIEW'in içerisindeki sorguda bulunan şarta uygun kayıtların INSERT edilmesine müsaade edilip, uymayan kayıtların müsaade edilmemesini sağlayan bir komuttur.
CREATE VIEW ORNEKVIEW2
AS
SELECT Adi,SoyAdi FROM Personeller WHERE Adi LIKE 'a%'
INSERT ORNEKVIEW2 ('AHMET','BİLMEMNEOĞLU')
INSERT ORNEKVIEW2 ('MUSA','UYUMAZ')
SELECT * FROM ORNEKVIEW2
- WITH ENCRYPTION ve WITH SCHEMABINDING komutları AS keywordünden önce belirtilirken WITH CHECK OPTION komutu WHERE şartından sonra belirtilmelidir.
CREATE VIEW ORNEKVIEW2
AS
SELECT Adi,SoyAdi FROM Personeller WHERE Adi LIKE 'a%'
WITH CHECK OPTION
-
T-SQL'de iki tip fonksiyon vardır.
-
SCALAR Fonksiyonlar => Geriye istediğimiz bir tipte değer gönderen fonksiyon.
-
INLINE Fonksiyonlar => Geriye tablo gönderen fonksiyon.
-
Bu her iki fonksiyonda fiziksel olarak veritabanında oluşturulmaktadır.
-
CREATE komutu ile oluşturulmaktadır.
-
Üzerinde çalışılan database'in Programability -> Functions kombinasyonundan oluşturulan fonksiyonlara erişebilmekteyiz.
- Scalar fonksiyonlara tanımlandıktan sonra Programmability -> Functions -> Scalar Valued Functions kombinasyonundan erişilebilir.
CREATE FUNCTION TOPLA(@SAYI1 INT, @SAYI2 INT) RETURNS INT
AS
BEGIN
RETURN @SAYI1 + @SAYI2
END
- Fonksiyonu kullanırken şemasıyla beraber çağrılmalıdır.
SELECT DBO.TOPLA(2,5)
PRINT DBO.TOPLA(10,20)
- ÖRNEK
- Northwind veritabanında; herhangi bir ürünün %18 KDV dahil olmak üzere toplam maliyetini getiren fonksiyonu yazalım.
CREATE FUNCTION MALIYET(@BIRIMFIYATI INT, @STOKMIKTARI INT) RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @SONUC INT = @BIRIMFIYATI * @STOKMIKTARI * 1.18
RETURN @SONUC
END
SELECT DBO.MALIYET(10,20)
-
Geriye bir değer değil tablo döndüren fonksiyonlardır.
-
Geriye tablo göndereceği için bu fonksiyonlar çalıştırılırken sanki bir tablodan sorgu çalıştırılır gibi çalıştırılırlar. Bu yönleriyle VIEW'lara benzerler. VIEW ile yapılan işlevler Inline Functions'larla yapılabilir.
-
Genellikle VIEW'le benzer işlevler için VIEW kullanılmasını öneririm.
-
Inline fonksiyonlara tanımlandıktan sonra Programmability -> Functions -> Table Valued Functions kombinasyonundan erişilebilir.
-
Dikkat ! ! !
-
Inline Function oluşturulurken BEGIN END yapısı kullanılmaz.
CREATE FUNCTION FC_GONDER(@AD NVARCHAR(20), @SOYAD NVARCHAR(20)) RETURNS TABLE
AS
RETURN SELECT Adi, SoyAdi FROM Personeller WHERE Adi = @AD AND SoyAdi = @SOYAD
- Fonksiyonu şemasıyla birlikte çağırmak gerekmektedir.
SELECT * FROM DBO.FC_GONDER('Nancy','Davolio')
-
Eğer ki yazmış olduğumuz fonksiyonların kodlarına 2. 3. şahısların erişimini engellemek istiyorsak WITH ENCRYPTION komutunu kullanmalıyız.
-
WITH ENCRYPTION işleminden sonra fonksiyonu oluşturan kişide dahil kimse komutları göremez. Geri dönüş yoktur. Ancak fonksiyonu oluşturan şahsın komutlarn yedeğini bulundurması gerekmektedir. Ya da WITH ENCRYPTION olmaksızın fonksiyonu yeniden ALTER'lamalıyız.
-
WITH ENCRYPTION AS keywordünden önce kullanılmalıdır.
CREATE FUNCTION ORNEKFONKSIYON() RETURNS INT
WITH ENCRYPTION
AS
BEGIN
RETURN 3
END
CREATE FUNCTION ORNEKFONKSIYON2() RETURNS TABLE
WITH ENCRYPTION
AS
RETURN SELECT * FROM Personeller
ALTER FUNCTION ORNEKFONKSIYON() RETURNS INT
AS
BEGIN
RETURN 3
END
- Herhangi bir kolonda fonksiyon kullanılarak otomatik hesaplanabilir kolonlar(Computed Column) oluşturmak mümkündür.
CREATE FUNCTION TOPLA(@SAYI1 INT, @SAYI2 INT) RETURNS INT
AS
BEGIN
RETURN @SAYI1 + @SAYI2
END
SELECT UrunAdi,DBO.TOPLA(BirimFiyati,HedefStokDuzeyi) HESAPLANMISKOLON FROM Urunler
- Örnek
- Çıktı olarak "____ kategorisindeki _____ ürününün toplam fiyatı : ____'dır. şeklinde bir çıktı veren fonksiyonu yazalım.
CREATE FUNCTION RAPOR(@KATEGORI NVARCHAR(MAX),@URUNADI NVARCHAR(MAX), @BIRIMFIYATI INT, @STOK INT) RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @CIKTI NVARCHAR(MAX) = @KATEGORI + ' kategorisindeki ' + @URUNADI + ' ürününün toplam fiyatı : ' + CAST(@BIRIMFIYATI * @STOK AS NVARCHAR(MAX)) + ' ''DIR.'
RETURN @CIKTI
END
SELECT DBO.RAPOR(K.KategoriAdi,U.UrunAdi,U.BirimFiyati,U.HedefStokDuzeyi) FROM Urunler U INNER JOIN Kategoriler K ON K.KategoriID = U.KategoriID
-
Normal sorgudan hızlı çalışırlar.
-
Çünkü normal sorgular Execute edilirken Execute Plan işlemi yapılır. Bu işlem sırasında hangi tablodan veri çekilecek hangi kolonlardan gelecek bunlar nerede vs. gibi işlemler yapılır. Bir sorgu her çalıştırıldığında bu işlemler aynen tekrar tekrar yapılır. Fakat sorgu STORED PROCEDURE olarak çalıştırılırsa bu işlem sadece bir kere yapılır ve o da ilk çalıştırma esnasındadır. Diğer çalıştırmalarda bu işlemler yapılmaz. Bundan dolayı hız ve performansta artış sağlanır.
-
İçerisinde SELECT INSERT UPDATE ve DELETE ilemleri yapılabilir.
-
İç içe kullanılabilir.
-
İçersinde fonksiyon oluşturulabilir.
-
Sorgularımızın dışarıdan alacağı değerler parametre olarak STORED PROCEDURE'lere geçirilebildiğinden dolayı sorgularımızın SQL INJECTION yemelerini de önlemiş oluruz. Bu yönleriyle de daha güvenlidirler.
-
STORED PROCEDURE fiziksel bir veritabanı nesnesidir. Haliyle CREATE komutu ile oluşturulur.
-
Fiziksel olarak ilgili veritabanının Programmability -> Stored Procedures kombinasyonundan erişilebilirler.
-- CREATE PROC YA DA PROCEDURE [İSİM]
--(
-- VARSA PARAMETRELER
--)AS
-- YAZILACAK SORGULAR, KODLAR, ŞARTLAR, FONKSİYONLAR, KOMUTLAR
CREATE PROC SP_ORNEK
(
@ID INT -- Aksi söylenmediği taktirde bu parametrenin yapısı inputtur.
)AS
SELECT * FROM Personeller WHERE PersonelID = @ID
- Prosedürün parametrelerini tanımlarken parantez kullanmak zorunlu değildir ama okunabilirliği arttırmak için kullanmakta fayda vardır.
CREATE PROC SP_ORNEK2
@ID INT,
@PARAMETRE2 INT,
@PARAMETRE3 NVARCHAR(MAX)
AS
SELECT * FROM Personeller WHERE PersonelID = @ID
- STORED PROCEDURE yapılarını EXEC komutu eşliğinde çalıştırabilmekteyiz.
EXEC SP_ORNEK 3
EXEC SP_ORNEK2 3,4,'ASD'
CREATE PROC URUNGETIR
(
@FIYAT MONEY
)AS
SELECT * FROM Urunler WHERE BirimFiyati > @FIYAT
RETURN @@ROWCOUNT
EXEC URUNGETIR 40
- Bu şekilde geriye döndürülen değeri elde etmeksizin kullanılabilir. Sıkıntı olmaz.
DECLARE @SONUC INT
EXEC @SONUC - URUNGETIR 40
PRINT CAST(@SONUC AS NVARCHAR(MAX)) + ' ADET ÜRÜN BU İŞLEMDEN ETKİLENMİŞTİR'
- INPUT parametre dışarıdan değer alırken OUTPUT parametre içerideki değeri dışarı gönderir.
CREATE PROC SP_ORNEK3
(
@ID INT,
@ADI NVARCHAR(MAX) OUTPUT,
@SOYADI NVARCHAR(MAX) OUTPUT
)AS
SELECT @ADI = Adi, @SOYADI = SoyAdi FROM Personeller WHERE PersonelID = @ID
DECLARE @ADI NVARCHAR(MAX), @SOYADI NVARCHAR(MAX)
EXEC SP_ORNEK3 3,@ADI OUTPUT, @SOYADI OUTPUT
SELECT @ADI + ' ' + @SOYADI
- Dışarıdan aldığı isim, soyisim ve şehir bilgilerini Personeller tablosunda ilgili kolonlara ekleyen STORED PROCEDURE'ü yazınız
CREATE PROC SP_PERSONELEKLE
(
@ISIM NVARCHAR(MAX),
@SOYISIM NVARCHAR(MAX),
@SEHIR NVARCHAR(MAX)
) AS
INSERT Personeller(Adi,SoyAdi,Sehir) VALUES(@ISIM, @SOYISIM, @SEHIR)
EXEC SP_PERSONELEKLE 'MUSA','UYUMAZ','ESKİŞEHİR'
SELECT * FROM PERSONELLER
CREATE PROC SP_PERSONELEKLE2
(
@AD VARCHAR(50) = 'İSİMSİZ',
@SOYAD VARCHAR(50) = 'SOYİSİMSİZ',
@SEHIR VARCHAR(50) = 'ŞEHİR GİRİLMEMİŞ'
)AS
INSERT Personeller(Adi,SoyAdi,Sehir) VALUES(@AD,@SOYAD,@SEHIR)
EXEC SP_PERSONELEKLE2 'SERHAT','UYUMAZ','ESKİŞEHİR'
- Burada varsayılan değerler devreye girmemektedir.
SELECT * FROM Personeller
EXEC SP_PERSONELEKLE2
- Normalde bu şekilde parametrelere değer göndermeksizin çalışmaması lazım ama varsayılan değerler tanımda belirtildiği için devreye girmektedirler.
Exec SP_PERSONELEKLE2 'İBRAHİM'
- @Ad parametresi İBRAHİM değerini alacaktır. Diğer parametreler varsayılan değerleri
-
EXEC Komutu EXECUTE yani çalıştır manasına gelen bir komuttur.
-
T-SQL programlama dilindeki herşeyi çalıştırır diyebiliriz.
-
EXEC sanki bir fonksiyon niteliğinde çalışan tek tırnaklar arasına aldığı komutları çalıştıran bir komuttur.
-
Aslında yazdığımız sorgular/komutlar arka planda EXEC komutunun içinde gönderilir.
EXEC('SELECT * FROM Personeller')
SELECT * FROM Personeller
- Yanlış Kullanım
EXEC('DECLARE @SAYAC INT = 0')
EXEC('PRINT @SAYAC')
- Doğru Kullanım
EXEC('DECLARE @SAYAC INT = 0 PRINT @SAYAC')
CREATE PROC SP_TABLOOLUSTUR
(
@TABLOADI NVARCHAR(MAX),
@KOLON1ADI NVARCHAR(MAX),
@KOLON1OZELLIKLERI NVARCHAR(MAX),
@KOLON2ADI NVARCHAR(MAX),
@KOLON2OZELLIKLERI NVARCHAR(MAX)
)AS
EXEC
('
CREATE TABLE '+ @TABLOADI + '
(
' + @KOLON1ADI + ' ' + @KOLON1OZELLIKLERI + ',
' + @KOLON2ADI + ' ' + @KOLON2OZELLIKLERI + ',
)
')
EXEC SP_TABLOOLUSTUR 'ORNEKTABLO3','ID','INT PRIMARY KEY IDENTITY(1,1)', 'KOLON2','NVARCHAR(MAX)'
- Bir işlem yapılırken o işlemin yerine ya da o işlemle beraber başka bir işlemin yapılmasını sağlayan başka bir işlemi tetikleyen yapılardır.
- Bir tabloda INSERT, UPDATE ve DELETE işlemleri gerçekleştirildiğinde devreye giren yapılardır. Bu işlemler sonucunda veya sürecinde devreye girerler.
- CREATE, ALTER ve DROP işlemleri sonucunda veya sürecinde devreye girecek olan yapılardır.
- Bir tabloda INSET, UPDATE ve DELETE işlemleri gerçekleştirildiğinde devreye giren yapılardır. Bu işlemler sonucunda veya sürecinde devreye girerler.
- Eğer bir tabloda INSERT işlemi yapılıyorsa arka planda işlemler ilk önce RAM'de oluşturulan INSERTED isimli bir tablo üzerinde yapılır. Eğer işlemde bir problem yoksa INSERTED tablosundaki veriler fiziksel tabloya INSERT edilir. İşlem bittiğinde RAM'de oluşturulan bu INSERTED tablosu silinir.
-
Eğer bir tabloda DELETE işlemi yapılıyorsa arka planda işlemler ilk önce RAM'de oluşturulan DELETED isimli bir tablo üzerinde yapılır. Eğer işlemde bir problem yoksa DELETED tablosundaki veriler fiziksel tabloya INSERT edilir. İşlem bittiğinde RAM'de oluşturulan bu DELETED tablosu silinecektir.
-
Eğer bir tabloda UPDATE işlemi yapılıyorsa RAM'de UPDATED isimli bir tablo OLUŞTURULMAZ! ! !
-
SQL Server'da ki UPDATE mantığı önce silme(DELETE) sonra eklemedir(INSERT).
-
Eğer bir tabloda UPDATE işlemi yapılıyorsa arka planda RAM'de hem DELETED hem de INSERTED tabloları oluşturulur ve işlemler bunlar üzerinde yapılır.
NOT : UPDATE yaparken güncellenen kaydın orjinali DELETED tablosunda, güncellendikten sonraki hali ise INSERTED tablosunda bulunmaktadır. Çünkü güncelleme demek kaydı önce silmek sonra eklemek demektir.
- DELETED ve INSERTED tabloları, ilgili sorgu sonucu oluştukları için o sorgunun kullandığı kolonlara da sahip olur. Böylece DELETED ve INSERTED tablolarından SELECT sorgusu yapmak mümkündür.
- CREATE TRIGGER [TRIGGER ADI]
- ON [İŞLEM YAPILACAK TABLO ADI]
- AFTER -- veya FOR DELETE, UPDATE, INSERT
- AS
- [KODLAR]
- Tanımlanan TRIGGER'larla ilgili tablonun içerisindeki TRIGGERS sekmesi altından erişebiliriz
CREATE TRIGGER ORNEKTRIGGER
ON Personeller
AFTER INSERT
AS
SELECT * FROM Personeller
INSERT Personeller(Adi,SoyAdi) VALUES('MUSA','UYUMAZ')
- Örnek 1
- Tedarikçiler tablosundan bir veri silindiğinde tüm ürünlerin fiyatı otomatik olarak 10 artsın.
CREATE TRIGGER TRIGGERTEDARIKCILER
ON Tedarikciler
AFTER DELETE
AS
UPDATE Urunler SET BirimFiyati = BirimFiyati + 10
SELECT * FROM URUNLER
DELETE FROM Tedarikciler WHERE TedarikciID = 31
- Örnek 2
- Tedarikçiler tablosunda bir veri güncellendiğinde, kategoriler tablosunda meyve kokteyli adında bir kategori oluşsun :)
CREATE TRIGGER TRGTEDARIKGUNCELLENDIGINDE
ON Tedarikciler
AFTER UPDATE
AS
INSERT Kategoriler(KategoriAdi) VALUES('MEYVE KOKTEYLİ')
UPDATE Tedarikciler SET MusteriAdi = 'SERHAT' WHERE TedarikciID = 29
SELECT * FROM Kategoriler
- Örnek 3
- Personeller tablosundan bir kayıt silindiğinde silinen kaydın adı, soyadı, kim tarafından ve hangi tarihte silindiği başka bir tabloya kayıt edilsin Bir nevi log tablosu misali...
CREATE TABLE LOGTABLOSU
(
ID INT PRIMARY KEY IDENTITY(1,1),
RAPOR NVARCHAR(MAX)
)
CREATE TRIGGER TRIGGERPERSONELLER
ON Personeller
FOR DELETE
AS
DECLARE @ADI NVARCHAR(MAX), @SOYADI NVARCHAR(MAX)
SELECT @ADI = Adi, @SOYADI = SoyAdi FROM DELETED
INSERT LOGTABLOSU(RAPOR) VALUES('ADI VE SOYADI ' + @ADI + ' ' + @SOYADI + ' OLAN PERSONEL ' +SUSER_NAME() + ' TARAFINDAN ' + CAST(GETDATE() AS NVARCHAR(MAX)) + ' TARİHİNDE SİLİNMİŞTİR.')
DELETE FROM Personeller WHERE PersonelID = 16
- Örnek 4
- Personeller tablosunda update gerçekleştiği anda devreye giren ve bir log tablosuna Adı ... olan personel ... yeni adıyla değiştirilerek ... kullanıcı tarafından ... tarihinde güncellendi. Kalıbında rapor yazan trigger'ı yazalım.
CREATE TRIGGER TRGPERSONELRAPOR
ON Personeller
AFTER UPDATE
AS
DECLARE @ESKIISIM NVARCHAR(MAX), @YENIISIM NVARCHAR(MAX)
SELECT @ESKIISIM = Adi FROM deleted
SELECT @YENIISIM = Adi FROM inserted
INSERT LOGTABLOSU(RAPOR) VALUES('Adı '+ @ESKIISIM +' olan personel ' + @YENIISIM +' yeni adıyla değiştirilerek ' + SUSER_NAME() +' kullanıcısı tarafından ' +CAST(GETDATE() AS NVARCHAR(MAX))+ ' tarihinde güncellendi.')
UPDATE Personeller SET Adi = 'MUSA' WHERE PersonelID = 3
SELECT * FROM LOGTABLOSU
CREATE TRIGGER MULTITRIGGER
ON PERSONELLER
AFTER DELETE, INSERT
AS
PRINT 'MERHABA'
INSERT Personeller(Adi,SoyAdi) VALUES('MUSA','UYUMAZ')
DELETE FROM Personeller WHERE PersonelID = 30
-
Şu ana kadar INSERT UPDATE ve DELETE işlemleri yapılırken şu şu işlemleri yap mantığıyşa çalıştık.(Yanında şunu yap)
-
Instead Of Triggerlar ise INSERT UPDATE ve DELETE işlemleri yerine şu şu işleri yap mantığıyla çalışmaktadır. (Yerine Şunu Yap)
-
CREATE TRIGGER [TRIGGER ADI]
-
ON [TABLO ADI]
-
INSTEAD OF DELETE INSERT UPDATE
-
AS
-
[KOMUTLAR]
-
Örnek 5
-
Personeller tablosunda UPDATE gerçekleştiği anda yapılacak güncelleştirme yerine bir log tablosuna ADI ... olan personel ... yani adıyla değiştirilerek ... kullanıcı tarafından ... tarihinde güncellenmek istendi. kalıbında rapır yazan trigger'ı yazalım.
CREATE TRIGGER TRGPERSONELLERRAPORINSTEAD
ON PERSONELLER
INSTEAD OF UPDATE
AS
DECLARE @ESKIADI NVARCHAR(MAX), @YENIADI NVARCHAR(MAX)
SELECT @ESKIADI = Adi FROM deleted
SELECT @YENIADI = Adi FROM inserted
INSERT LOGTABLOSU(RAPOR) VALUES('Adı '+ @ESKIADI +' olan personel ' + @YENIADI +' yeni adıyla değiştirilerek ' + SUSER_NAME() +' kullanıcısı tarafından ' +CAST(GETDATE() AS NVARCHAR(MAX))+ ' tarihinde istendi.')
UPDATE Personeller SET Adi = 'HÜSEYİN' WHERE PersonelID = 15
- Örnek 6
- Personeller tablosunda adı Andrew olan kaydın ilinmesini engelleyen ama diğerlerine izin veren trigger'ı yazalım.
CREATE TRIGGER AndrewTrigger
ON PERSONELLER
AFTER DELETE
AS
DECLARE @ADI NVARCHAR(MAX)
SELECT @ADI = Adi FROM deleted
IF @ADI = 'Andrew'
BEGIN
PRINT 'Bu kaydı Silemezsiniz.'
ROLLBACK -- Yapılan tüm işlemleri geri alır.
END
DELETE FROM Personeller WHERE PersonelID = 17
- CREATE, ALTER ve DROP işlemleri sonucunda veya sürecinde devreye girecek olan yapılardır.
CREATE TRIGGER DDL_TRIGGER
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE, CREATE_FUNCTION, CREATE_PROCEDURE, DROP_PROCEDURE --VS. VS.
AS
PRINT 'BU İŞLEM GERÇEKLEŞTİRİLEMEZ'
ROLLBACK
DROP TABLE LOGTABLOSU
- DDL TRİGGER'larla ilgili veritabanının Programmability -> Database Triggers sekmesi altından erişebilirsiniz.
DISABLE TRIGGER ORNEKTRIGGER ON PERSONELLER
ENABLE RIGGER ORNEKTRIGGER ON PERSONELLER
-
Birden çok işlemin bir arada yapıldığı durumlarda eğer parçayı oluşturan işlemlerden herhangi birinde sorun olursa tüm işlemi iptal ettirmeye yarar.
-
Örneğin; kredi kartı ile alışveriş işlemlerinde transaction işlemi vardır. Siz marketten ürün alırken sizin hesabınızdan para düşülecek, marketin hesabına para aktarılıcaktır. Bu işlemde hata olmaması gerekir ve bundan dolayı bu işlem bir transaction bloğunda gerçekleştirilmelidir. Bu esnada herhangi bir sorun olursa bütün işlemler transaction tarafından iptal edilebilecektir.
-
BEGIN TRAN veya BEGIN TRANSACTION : Transaction işlemi başlatır.
-
COMMIT TRAN : Transaction işlemini başarıyla sına erdirir. İşlem(ler)i gerçekleştirir.
-
ROLLBACK TRAN : Transaction işlemini iptal eder. İşlem(ler)i geri alır.
-
COMMIT TRAN yerine sadece COMMIT yazılabilir
-
ROLLBACK TRAN yerine sadece ROLLBACK yazılabilir.
-
Normalde default olarak herşey BEGIN TRAN ile başlayıp COMMIT TRAN ile biter. !!! Biz bu yapıları kullanmasak bile!!!
- BEGIN TRAN [TRANSACTION ADI]
- İŞLEMLER
INSERT Bolge VALUES(5,'Çorum') -- Varsayılan olarak TRANSACTION kontrolünde bir işlemdir. Netice olarak gene varsayılan olarak COMMIT TRAN olarak bitmektedir.
BEGIN TRAN KONTROL
INSERT Bolge VALUES(6,'Ankara')
COMMIT TRAN
- Transaction'a isim vermek zorunda değiliz.
BEGIN TRAN
INSERT Bolge VALUES(7,'Antalya')
COMMIT TRAN
BEGIN TRAN KONTROL
DECLARE @i int
DELETE FROM Personeller WHERE PersonelID > 20
SET @i = @@ROWCOUNT
IF @i = 1
BEGIN
PRINT 'KAYIT SİLİNDİ.'
COMMIT
-- YA DA
-- COMMIT TRAN
END
ELSE
BEGIN
PRINT 'İşlemler geri alındı'
ROLLBACK
-- YA DA
-- ROLLBACK TRAN
END
- İki adet banka tablosu oluşturalım. Bankalar arası havale işlemi gerçekleştirelim. Ve bu işlemleri yaparken transaction kullanalım.
CREATE DATABASE BANKADB
GO
USE BANKADB
GO
CREATE TABLE ABANKA
(
HESAPNO INT,
BAKIYE MONEY
)
GO
CREATE TABLE BBANKA
(
HESAPNO INT,
BAKIYE MONEY
)
GO
INSERT ABANKA VALUES(10,1000),
(20,2500)
INSERT BBANKA VALUES(30,2300),
(40,760)
GO
CREATE PROC SP_HAVALEYAP
(
@BANKAKIMDEN NVARCHAR(MAX),
@GONDERENHESAPNO INT,
@ALANHESAPNO INT,
@TUTAR MONEY
)AS
BEGIN TRANSACTION KONTROL
DECLARE @ABAKIYE INT, @BBAKIYE INT, @HESAPTAKIPARA MONEY
IF @BANKAKIMDEN = 'ABANKA'
BEGIN
SELECT @HESAPTAKIPARA = BAKIYE FROM ABANKA WHERE HESAPNO=@GONDERENHESAPNO
IF @TUTAR > @HESAPTAKIPARA
BEGIN
PRINT CAST(@GONDERENHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTA GÖNDERİLMEK İSTENEN TUTARDAN DAHA AZ PARA MEVCUTTUR.'
ROLLBACK -- İŞLEMLERİ GERİ AL
END
ELSE
BEGIN
UPDATE ABANKA SET BAKIYE = BAKIYE - @TUTAR WHERE HESAPNO = @GONDERENHESAPNO
UPDATE BBANKA SET BAKIYE = BAKIYE + @TUTAR WHERE HESAPNO = @ALANHESAPNO
PRINT 'ABANKASINDAKİ '+ CAST(@GONDERENHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTAN ABANKASINDAKİ ' +CAST(@ALANHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESABA ' + CAST(@TUTAR AS NVARCHAR(MAX)) + ' DEĞERİNDE PARA HAVALE EDİLMİŞTİR.'
PRINT 'SON DEĞERLER;'
SELECT @BBAKIYE=BAKIYE FROM BBANKA WHERE HESAPNO = @ALANHESAPNO
SELECT @ABAKIYE=BAKIYE FROM ABANKA WHERE HESAPNO = @GONDERENHESAPNO
PRINT 'ABANKASINDAKİ ' + CAST(@GONDERENHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTA KALAN BAKİYE : ' + CAST(@ABAKIYE AS NVARCHAR(MAX))
PRINT 'BBANKASINDAKİ ' + CAST(@ALANHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTA KALAN BAKİYE : ' + CAST(@BBAKIYE AS NVARCHAR(MAX))
COMMIT
END
END
ELSE
BEGIN
SELECT @HESAPTAKIPARA=BAKIYE FROM BBANKA WHERE HESAPNO = @GONDERENHESAPNO
IF @TUTAR > @HESAPTAKIPARA
BEGIN
PRINT CAST(@GONDERENHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTA GÖNDERİLMEK İSTENEN TUTARDAN DAHA AZ PARA MEVCUTTUR.'
ROLLBACK -- İŞLEMLERİ GERİ AL
END
ELSE
BEGIN
UPDATE BBANKA SET BAKIYE = BAKIYE - @TUTAR WHERE HESAPNO = @GONDERENHESAPNO
UPDATE ABANKA SET BAKIYE = BAKIYE + @TUTAR WHERE HESAPNO = @ALANHESAPNO
PRINT 'BBANKASINDAKİ '+ CAST(@GONDERENHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTAN ABANKASINDAKİ ' +CAST(@ALANHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESABA ' + CAST(@TUTAR AS NVARCHAR(MAX)) + ' DEĞERİNDE PARA HAVALE EDİLMİŞTİR.'
PRINT 'SON DEĞERLER;'
SELECT @BBAKIYE=BAKIYE FROM BBANKA WHERE HESAPNO = @GONDERENHESAPNO
SELECT @ABAKIYE=BAKIYE FROM ABANKA WHERE HESAPNO = @ALANHESAPNO
PRINT 'ABANKASINDAKİ ' + CAST(@ALANHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTA KALAN BAKİYE : ' + CAST(@ABAKIYE AS NVARCHAR(MAX))
PRINT 'BBANKASINDAKİ ' + CAST(@GONDERENHESAPNO AS NVARCHAR(MAX)) + ' NUMARALI HESAPTA KALAN BAKİYE : ' + CAST(@BBAKIYE AS NVARCHAR(MAX))
COMMIT
END
END
EXEC SP_HAVALEYAP 'ABANKA', 10,30,100
EXEC SP_HAVALEYAP 'BBANKA', 30,10,300
EXEC SP_HAVALEYAP 'ABANKA',20,40,5000
-- T-SQL En Son Primary Key ID'yi Bulmak
SELECT IDENT_CURRENT('Personeller')
SELECT IDENT_CURRENT('Personeller') + 1
- Açılmış olan bağlantıda(connection); tablo yahut sorgunun çalıştığı scope'a bakmaksızın son üretilen identity değerini vermektedir.
- Trigger kullanılan sorgularda yanlış sonuç alma ihtimalinden dolayı kullanılması tavsiye edilmez.
INSERT Personeller(Adi,SoyAdi) VALUES('MUİDDİN','İMPATRİNO')
SELECT @@IDENTITY
- Açılmış olan bağlantıda(connection) ve sorgunun çalıştığı scope'ta son üretilen identity değerini döndürür.
- Trigger kullanılan sorgularda @@IDENTITY yerine bu fonksiyonun kullanılması tavsiye edilir.
INSERT Personeller(Adi,SoyAdi) VALUES('MUİDDİN','İMPATRİNO')
SELECT SCOPE_IDENTITY()
- Bağlantı ve sorgunun çalıştırıldığı scope'a bakmaksızın parametre olarak verilen tabloda üretilen sonuncu identity değerini döndürür.
CREATE DATABASE ORNEKVERITABANI
GO
CREATE TABLE ORNEKTABLO1
(
ID INT PRIMARY KEY IDENTITY,
KOLON1 NVARCHAR(MAX),
KOLON2 NVARCHAR(MAX),
)
GO
CREATE TABLE ORNEKTABLO2
(
ID INT PRIMARY KEY IDENTITY,
KOLON1 NVARCHAR(MAX),
KOLON2 NVARCHAR(MAX),
)
USE ORNEKVERITABANI
CREATE TRIGGER KONTROL
ON ORNEKTABLO1 FOR INSERT
AS
INSERT ORNEKTABLO2 VALUES('','')
INSERT ORNEKTABLO2 VALUES('1','1')
INSERT ORNEKTABLO2 VALUES('2','2')
INSERT ORNEKTABLO2 VALUES('3','3')
INSERT ORNEKTABLO2 VALUES('4','4')
INSERT ORNEKTABLO2 VALUES('5','5')
INSERT ORNEKTABLO1 VALUES('6','6')
SELECT @@IDENTITY
UNION ALL
SELECT SCOPE_IDENTITY()
UNION ALL
SELECT IDENT_CURRENT('ORNEKTABLO1')
- Eğer ki veritabanında görevi sadece diğer tablolar tarafından referans alınacağı ideleri üretecek ve barındıracak olan bir tabloya ihtiyacınız varsa kullanılır.
CREATE DATABASE ORNEKVERITABANI
CREATE TABLE ORNEKTABLO
(
ID INT PRIMARY KEY IDENTITY,
KOLON1 NVARCHAR(MAX),
KOLON2 NVARCHAR(MAX),
)
USE ORNEKVERITABANI
INSERT ORNEKTABLO
DEFAULT VALUES
- Biz herhangi bir UPDATE işleminde herhangi bir filtreleme uygulayabiliriz ama yapacağımız filtrelemede ilklik ya da sonluk gerekiyorsa bunu TOP komutuyla yapmamız daha doğru olacaktır.
CREATE TABLE VERILER
(
ID INT PRIMARY KEY IDENTITY,
DEGER INT
)
DECLARE @I INT = 1
WHILE @I < 151
BEGIN
INSERT VERILER(DEGER) VALUES(@I)
SET @I = @I + 1
END
SELECT TOP 2 * FROM Personeller
SELECT * FROM Veriler
UPDATE VERILER SET DEGER = DEGER - 5 WHERE ID <= 10
UPDATE TOP(10) VERILER SET DEGER = DEGER - 5
SELECT * FROM VERILER
DELETE FROM VERILER WHERE ID > 100
DELETE FROM VERILER WHERE ID<=10
DELETE TOP(5) FROM VERILER
-
T-SQL'de SELECT sorgusu neticesinde yapısal olarak elde ettiğimiz tabloların satır index numaralarına ihtiyacımız olabilir.
-
Veritabanında tekrar eden datalar/veriler varsa veriler arasında ayrım yapmak yahut sıralamak gibi işlemler yapmak istiyorsak ROW_NUMBER() fonksiyonunu kullanabiliriz.
-
Temelde işlevi her satıra karşılık PRIMARY kolonundan bağımsız sıralı index numarası atanmış kolon tanımlanmaktadır.
- SELECT ROW_NUMBER() OVER(ORDER BY KOLONADI) INDEXER, * FROM TABLO
SELECT ROW_NUMBER() OVER(ORDER BY Adi) INDEXER, * FROM Personeller ORDER BY PersonelID
- SELECT ROW_NUMBER() OVER(PARTITION BY KOLON1 ORDER BY KOLON2) INDEXER, * FROM TABLO
SELECT ROW_NUMBER() OVER(PARTITION BY MusteriID ORDER BY OdemeTarihi) INDEXER,* FROM Satislar ORDER BY SatisID
-
SET ANSI_NULLS [ON | OFF]
-
ANSI_NULLS komutu, WHERE şartlarında kontrol edilen eşitlik yahut eşit değillik durumlarında NULL değerlerin dikkate alınıp alınmayacağını belirlememizi sağlayan bir özelliktir.
-
'ON' değeri verilirse NULL değerler dikkate alınmaz.
-
'OFF' değeri verilirse NULL değerler dikkate alınır.
SET ANSI_NULLS ON
SELECT * FROM PersonelMaas WHERE Maas = NULL
SET ANSI_NULLS OFF
-
Dinamik veri maskeleme sistemidir.
-
Veritabanında ilişkisel tablolarımızda tuttuğumuz verilerimizi tararken gösterilmesi istenen veriler dışındaki verileri maskeleme özelliğidir.
-
Verinin orjinal halini yani fiziksel yapısını değiştirmeden kullanıcıya bir kısmını göstermek yahut gizlemektir.
-
Bir alışveriş sitesinde kayıtlı kullanıcının her bilgisine örneğin tc kimlik numarasına, kredi kartı numarasına, telefon numarasına, ev adresine bunun gibi kritik bilgilere biz kritik görevler dışındakilerin personellerin ulaşmasını istemeyiz.
-
Bir nevi güvenlik önlemi olsada amaca dönük sorguların gerçekleştirilmesini sağlamaktır.
-
Dynamic Data Masking default, email ve partial olmak üzere 3 adet fonksiyonel parametre ile çalışmaktadır.
- Metinsel : XXXX
- Sayısal : 0000
- Tarihsel : 01.01.2000 00:00:00.0000000
- Binary : 0 -> ASCII
- Partial(3,H,2)
- CREATE TABLE [TABLO ADI] -(
- [KOLON ADI] [KOLON TİPİ] MASKED WITH(FUNCTION = 'DEFAULT()') -)
CREATE TABLE OGRENCILER2
(
OGRENCIID INT PRIMARY KEY IDENTITY,
ADI NVARCHAR(10) MASKED WITH (FUNCTION = 'DEFAULT()') NULL,
SOYADI NVARCHAR(10) MASKED WITH (FUNCTION = 'DEFAULT()') NULL,
MEMLEKETI NVARCHAR(10) MASKED WITH (FUNCTION = 'DEFAULT()') NULL,
TCNO INT MASKED WITH (FUNCTION = 'DEFAULT()') NULL,
SUBE NVARCHAR(1) MASKED WITH (FUNCTION = 'DEFAULT()') NULL,
EMAIL NVARCHAR(MAX) MASKED WITH (FUNCTION = 'EMAIL()') NULL,
HAKKINDA NVARCHAR(MAX) MASKED WITH (FUNCTION = 'PARTIAL(3,"H",2)') NULL,
DOGUMTARIHI DATETIME MASKED WITH (FUNCTION = 'DEFAULT()') NULL,
)
INSERT OGRENCILER2 VALUES('MUSA','UYUMAZ','ESKİŞEHİR',1234,'A','musa.uyumaz73@gmail.com','Türk Milletine Canım Feda Olsun...','1999-02-14')
INSERT OGRENCILER2 VALUES('GENÇAY','YILDIZ','ARTVİN',1234,'A','gncy@gencayyildiz.com','Türk Milletine Canım Feda Olsun...','1992-09-05')
INSERT OGRENCILER2 VALUES('İBRAHİM','YILDIRIM','MALATYA',1234,'B','ibrahim@yildirim.com','Türk Milletine Canım Feda Olsun...','1975-09-05')
SELECT * FROM OGRENCILER2
CREATE USER YETKILIUSER WITHOUT LOGIN --YETKILIUSER isminde bir kullanıcı oluşturuluyor.
GO
GRANT SELECT ON OGRENCILER2 TO YETKILIUSER --YETKILIUSER isimli kullanıcıya OGRENCILER2 tablosunda SELECT yetkisi veriliyor.
EXECUTE AS USER = 'YETKILIUSER' -- YETKILIUSER isimli kullanıcıya geçiş sağlıyoruz.
SELECT * FROM OGRENCILER2
ALTER TABLE OGRENCILER2
ADD EKKOLON NVARCHAR(MAX) MASKED WITH (FUNCTION = 'PARTIAL(3,"XXX",0)')
EXECUTE AS USER = 'YETKILIUSER'
SELECT * FROM OGRENCILER2
ALTER TABLE OGRENCILER2
ADD EKKOLON NVARCHAR(MAX) MASKED WITH (FUNCTION = 'PARTIAL(3,"XXX",0)')
ALTER TABLE OGRENCILER2
ADD EKKOLON NVARCHAR(MAX) MASKED WITH (FUNCTION = 'PARTIAL(2,"AAA",4)')
EXECUTE AS USER='YETKILIUSER'
SELECT * FROM OGRENCILER2
ALTER TABLE OGRENCILER2
ALTER COLUMN EMAIL DROP MASKED
EXECUTE AS USER='YETKILIUSER'
SELECT * FROM OGRENCILER2
GRANT UNMASK TO YETKILIUSER
EXECUTE AS USER = 'YETKILIUSER'
SELECT * FROM OGRENCILER2
-
Veritabanında yapılan DML işlemlerini raporlamamızı sağlayan bir yapıdır.
-
Tablomuzda bulunan kayıtların zaman içinde değişikliklerini yani UPDATE güncelleme dediğimiz bu değişiklikleri izlenmesini ve takip edilmesini sağlayan bir yapı sunmaktadır.
-
Tablo üstünde yanlışlıkla yapılan DELETE ve UPDATE sorgularını geri getirilmesini sağlamaktadır.
-
Bir verinin belirli bir zamana yahut zaman aralığına odaklı izlenebilmesini de sağlayabiliyoruz.
-
== Veri İlk Kaydedildiğinde (INSERT)==
-
== Veri İlk Güncellendiğinde (UPDATE)==
-
== Verinin Sonraki Güncellemelerinde (UPDATE)==
-
Temporal Tables ile raporlama ve takip mekanizmasını oluşturacağımız tablolarda PRIMARY KEY tanımlanmış bir kolon olması gerekmektedir. Bu şekilde yaşam döngüsünde hangi verinin değişime uğradığını PRIMARY KEY aracılığıyla ayırt edebileceğiz.
-
Takibi sağlayacağımız ve kaydınıu tutacağımız tablomuzun içerisinde bir başlangıç(StartDate) birde bitiş(EndDate) niteliğinde iki adet DATETIME2 tipinden kolonların bulunması gerekmektedir.
-
Linked Server üzerinde Temporal Tables kullanılmamaktadır.
-
History tablomuzda constraint yapılarının hiçbirini uygulayamayız.
-
Eğer bir tabloda Temporal Tables aktifse o tabloda TRUNCATE işlemi gerçekleştiremiyoruz.
-
History tablosunda direkt olarak DML işlemleri gerçekleştiremiyoruz.
-
Temporal Tables özelliğinin bulunduğu bir tabloda Computed Column(Hesaplanmış Kolon) tanımlayamıyoruz.
UPDATE DERSKAYITLARI SET DERS = 'MATEMATİK2' WHERE DERSID = 1
UPDATE DERSKAYITLARI SET DERS = 'FİZİK2' WHERE DERSID = 2
UPDATE DERSKAYITLARI SET DERS = 'KİMYA2' WHERE DERSID = 3
UPDATE DERSKAYITLARI SET DERS = 'KİMYA3' WHERE DERSID = 3
UPDATE DERSKAYITLARI SET DERS = 'BİYOLOJİ2' WHERE DERSID = 4
UPDATE DERSKAYITLARI SET DERS = 'BİYOLOJİ3' WHERE DERSID = 4
SELECT * FROM DERSKAYITLARI
SELECT * FROM DERSKAYITLARILOG
CREATE TABLE DERSKAYITLARI
(
---------- 1. KISIM ----------
DERSID INT PRIMARY KEY IDENTITY(1,1),
DERS NVARCHAR(MAX),
ONAY BIT,
---------- 1. KISIM ----------
---------- 2. KISIM ----------
STARTDATE DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL,
ENDDATE DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL,
---------- 2. KISIM ----------
---------- 3. KISIM ----------
PERIOD FOR SYSTEM_TIME(STARTDATE,ENDDATE)
---------- 3. KISIM ----------
)
---------- 4. KISIM ----------
WITH(SYSTEM_VERSIONING = ON(HISTORY_TABLE = DBO.DERSKAYITLARILOG)) -- Eğer HISTORY_TABLE özelliği ile History tablosuna isim vermezsek rastgele isimde oluşturulur.
---------- 4. KISIM ----------
CREATE TABLE DERSKAYITLARI
(
DERSID INT PRIMARY KEY IDENTITY(1,1),
DERS NVARCHAR(MAX),
ONAY BIT
)
INSERT DERSKAYITLARI VALUES('MATEMATİK',1),
('FİZİK',1),
('KİMYA',1),
('TÜRKÇE',0),
('COĞRAFYA',0),
('VATANDAŞLIK',0)
-
Eğer bu tabloyu temporal yapmak istiyorsak dikkat ! ! !
-
Tablo içerisinde veri var mı? Yok mu? Eğer varsa yeni eklenecek olan StartDate ve EndDate kolonları boş kalamayacakları için varsayılan değerlerin belirtilmesi gerekmektedir. Yok eğer veri yoksa bu işlemi düşünmemize gerek olmayacaktır.
ALTER TABLE DERSKAYITLARI
ADD
STARTDATE DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL,
ENDDATE DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL,
PERIOD FOR SYSTEM_TIME(STARTDATE,ENDDATE)
ALTER TABLE DERSKAYITLARI
ADD
STARTDATE DATETIME2 GENERATED ALWAYS AS ROW START NOT NULL
DEFAULT CAST('1900-01-01 00:00:00.0000000' AS DATETIME2),
ENDDATE DATETIME2 GENERATED ALWAYS AS ROW END NOT NULL
DEFAULT CAST('9999-12-31 23:59:59.9999999' AS DATETIME2),
PERIOD FOR SYSTEM_TIME(STARTDATE,ENDDATE)
-
Şeklinde periyodik kayıt kolonlarımızı ekleyebiliriz.
-
Kolonlar eklendikten sonra ilgili tablo aşağıdaki gibi Temporal hale getirilir.
ALTER TABLE DERSKAYITLARI
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = DBO.DERSKAYITLARILOG))
-
SELECT * FROM DERSKAYITLARI DK INNER JOIN DERSKAYITLARILOG DKL ON DK.DERSID = DKL.DERSID WHERE DAY(DKL.STARTDATE) >= DAY(CAST 'TARİH' AS DATETIME2) OR DAY(DKL.ENDDATE) <= DAY(CAST('2016-09-26 06:23:45.8195851' AS DATETIME2))
-
Bu şekilde ilişkisel tablolar ile de sorgulama yapabiliriz. Lakin tablomuzu History tablosunun periyoduna özel bir şekilde de rahatça sorgulatabilmekteyiz.
- Mantıksal sorgusu : 'STARDATE >= DATETIME and ENDDATE < DATETIME' şeklindedir.
SELECT * FROM DERSKAYITLARI
FOR SYSTEM_TIME AS OF '2016-09-26 06:22:53.5432528' WHERE DERSID = 3
- Mantıksal sorgusu : 'start_datetime >= datetime and end_datetime < datetime' şeklindedir.
SELECT * FROM DERSKAYITLARI
FOR SYSTEM_TIME FROM '2016-09-26 06:22:53.5432528' TO '2016-09-26 06:22:53.5432528'
WHERE DERSID = 3
- Mantıksal sorgusu : 'start_datetime >= datetime and end_datetime < datetime' şeklindedir.
- Mantıksal sorgusu : 'start_datetime >= datetime and end_datetime < datetime' şeklindedir.
SELECT NAME,OBJECT_ID,TEMPORAL_TYPE_DESC, HISTORY_TABLE_ID, OBJECT_NAME(HISTORY_TABLE_ID) AS [HISTORY TABLO ADI] FROM SYS.TABLES WHERE OBJECT_NAME(HISTORY_TABLE_ID) IS NOT NULL
- ya da
SELECT NAME,OBJECT_ID,TEMPORAL_TYPE_DESC, HISTORY_TABLE_ID, OBJECT_NAME(HISTORY_TABLE_ID) AS [HISTORY TABLO ADI] FROM SYS.TABLES WHERE TEMPORAL_TYPE_DESC = 'SYSTEM_VERSIONED_TEMPORAL_TABLE'
ALTER TABLE DBO.DERSKAYITLARI SET(SYSTEM_VERSIONING = OFF)
TRUNCATE TABLE DERSKAYITLARI
DROP TABLE DERSKAYITLARI
-
Veritabanı yönetim sistemlerinde amacımız düzenli ve organize edilmiş ilişkisel bir şekilde verilerimizi modifiye etmektir. Bu amacı icra ederken güvenlik birinci dereceden önem teşkil etmekte ve çeşitli yöntemlerle güvenlik mekanizması sağlanmaktadır.
-
Bu yöntemler genellikle kullanıcı rol ve yetkilendirmeleriyle sağlanmaktayken verilere dönük oalrakta VIEW gibi yapılarla gerçekleştirilmektedir.
-
ROW LEVEL SECURITY özelliği ile Kullanıcılara tablo üzerinde yetki verirken tüm kayıtlara değil sadece kendisini ilgilendiren kayıtlara özel bir yetkilendirme yapabiliriz.
CREATE DATABASE YENILIKLER
GO
USE YENILIKLER
GO
CREATE TABLE SATISLAR
(
SATISID INT PRIMARY KEY IDENTITY,
URUN NVARCHAR(MAX),
ADET INT,
KULLANICI NVARCHAR(MAX)
)
GO
INSERT SATISLAR VALUES
('AURUN',3,'MUSA'),
('AURUN',3,'GENÇAY'),
('BURUN',5,'MEHMET'),
('CURUN',13,'ALİ'),
('DURUN',23,'GENÇAY'),
('EURUN',33,'MEHMET'),
('FURUN',43,'ALİ'),
('GURUN',53,'GENÇAY'),
('HURUN',63,'MEHMET'),
('IURUN',73,'ALİ'),
('OURUN',83,'GENÇAY'),
('PURUN',93,'MEHMET'),
('RURUN',133,'ALİ')
CREATE USER GENCAY WITHOUT LOGIN
CREATE USER MEHMET WITHOUT LOGIN
CREATE USER ALI WITHOUT LOGIN
GRANT SELECT ON SATISLAR TO GENCAY
GRANT SELECT ON SATISLAR TO MEHMET
GRANT SELECT ON SATISLAR TO ALI
- ROW LEVEL SECURITY kullanabilmek için Inline Table Value Function oluşturmalıyız.
CREATE FUNCTION ROWLEVELSECURITYFUNCTION (@KULLANICIADI AS SYSNAME)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 ROWLEVELRESULT
WHERE @KULLANICIADI = USER_NAME()
- Şimdi bu fonksiyonu birazdan oluşturacağımız Security Policy(Güvenlik Politikası) için Filter Predicate olarak ekliyoruz. Yani uzun lafın kısası filtre olarak ayarlıyoruz.
CREATE SECURITY POLICY GUVENLIKFILTRESI
ADD FILTER PREDICATE DBO.ROWLEVELSECURITYFUNCTION(KULLANICI)
ON DBO.SATISLAR
WITH(STATE = ON)
- KULLANILAN TÜM YAPIDA ŞEMA ADLARINI(.dbo) UNUTMA
EXEC AS USER = 'MEHMET'
SELECT * FROM SATISLAR