Arkadaslar Birçogunuzun Çok Isine Yarayacak Kapsamli SQL Sorgu Cümleciklerini Sizlerle Paylasmak Istiyorum. Buradaki Sorgular Norhwind Veritabani Esas Alinarak Hazirlanmistir. Ancak Sorgular Standart Oldugundan Her Veritabaninda Çalisir. Sadece Tablo ve db Adlari Degisir.
use Northwind
/*
T-SQL (Transactional - Structure Query Language), üç dil yapisinin birlesiminden olusur.
1. DDL : Data Definition Language
CREATE<NesneTipi><NesneAdi> (Olusturucu)
ALTER<NesneTipi><NesneAdi> (Degistirir)
DROP<NesneTipi><NesneAdi> (Siler)
2. DML : Data Manipulation Language
INSERT (Kayit Ekler)
UPDATE (Varolan Kaydi Günceller)
DELETE (Varolan Kaydi Siler)
SELECT (Belirtilen Kritere Uygun Kayitlari Getirir.)
*/
INSERT
INSERT into <TabloAdi> (<KolonAdi1>,<KolonAdi2>,<KolonAdiN>)
values (<Deger1>,<deger2>,<degerN>)
INSERT into Products (ProductName,UnitPrice,UnitsInStock,Discontinued)
values (’Kuru Fasülye’,5,1000,0)
UPDATE
UPDATE <tabloAdi> SET <KolonAdi1> = <Deger1>,
<KolonAdi2> = <Deger2>,
<KolonAdi3> = <Deger3>
WHERE <kriter>
UPDATE Products SET ProductName = ’Taze Fasülye’
WHERE ProductID = 78
DELETE
DELETE FROM <TabloAdi> WHERE<Kriter>
DELETE FROM Products WHERE ProductID = 78
SELECT
SELECT <KolonAdi1>,<KolonAdi2> FROM <TabloAdi> WHERE<VARSA kriter>
SELECT * FROM <TabloAdi> WHERE <VARSA kriter> (Tüm Kolonlari Getirir..)
SELECT * FROM Employees
SELECT FirstName, LastName FROM Employees
SELECT <TabloAdi>.<KolonAdi1>, FROM<TabloAdi>.<KolonAdi2> WHERE <VARSA kriter>
-- Uzunca..
SELECT Products.ProductName, Products.UnitPrice FROM Products
WHERE UnitPrice > 100
-- 100 $ dan büyük ürünler..
UnitsInStock (stok) degeri 10’un altinda olan ürünlerin adi, fiyati ve stok bilgileri
SELECT Products.ProductName, Products.UnitPrice, Products.UnitsInStock FROMProducts
WHERE UnitsInStock < 10
/*
1. Hangi tablo(lar) ile çalisacagina karar ver.
2. Bu tablo(lar) daki hangi kolon(lar)i görmek istedigine karar ver.
3. Eger varsa kriterini yaz.
*/
Brazil’de bulunan müsterilerin Sirket Adi, TemsilciAdi, Adres, Sehir, Ülke bilgileri
SELECT CompanyName, ContactName, Address, City, Country FROMCustomers
WHERE Country = ’Brazil’
Brezilya’daolmayan müsteriler
SELECT CompanyName,ContactName,Address,City,Country FROMCustomers
WHERE Country != ’Brazil’
Londra’da ya da Paris’de bulunan müsterilerim:
SELECT CustomerID,CompanyName,Address, City FROM Customers
WHERE City = ’London’ OR City = ’Paris’
Hem Mexico D.F’da ikamet eden HEM DE ContactTitle bilgisi ’owner’ olan müsteriler:
SELECT CustomerID,CompanyName,ContactTitle,City FROM Customers
WHERE City = ’México D.F.’ AND ContactTitle = ’owner’
C ile baslayan ürünlerimin isimleri ve fiyatlari
SELECT ProductName,UnitPrice FROM Products
WHERE ProductName LIKE ’C%’
Satisi yapilmayan ürün listesi
(Ipucu: Discontinued=1 olacak)
SELECT ProductName,UnitPrice FROM Products
WHERE Discontinued = 1
Adi (FirstName) ’A’ harfiyle baslayan çalisanlarin (Employees); Ad, Soyad ve Dogum Tarihlerini görmek istiyorsak:
SELECT FirstName,LastName,BirthDate FROM Employees
WHERE FirstName LIKE ’A%’
Isminde ’RESTAURANT’ geçen müsterilerimin sirket adlari:
SELECT CompanyName FROM Customers
WHERE CompanyName LIKE ’%RESTAURANT%’
50$ ile 100$ arasinda bulunan tüm ürünlerin adlari ve fiyatlari
SELECT ProductName,UnitPrice FROM Products
WHERE UnitPrice BETWEEN 50 AND 100
1 temmuz 1996 ile 31 Aralik 1996 tarihleri arasindaki siparislerin (Orders), SiparisID (OrderID) ve SiparisTarihi (OrderDate) bilgileri
SELECT OrderID,OrderDate FROM Orders
WHERE OrderDate BETWEEN ’01/07/1996’ AND ’31/12/1996’
Ülkesi (Country) Ya Spain, Ya France, Ya da Germany olan müsteriler
SELECT CompanyName,Country FROM Customers
WHERE Country = ’Spain’ OR Country = ’France’ OR Country = ’Germany’
Eger OR çok fazla kullanmissak, asagidaki gibi de yazabiliriz.
SELECT CompanyName,Country FROM Customers
WHERE Country IN (’Spain’,’France’,’Germany’)
Olumsuzu (NOT IN)
SELECT CompanyName,Country FROM Customers
WHERE Country NOT IN (’Spain’,’France’,’Germany’)
Faks numarasini bilmedigim müsteriler
SELECT CustomerID, CompanyName, Fax FROM Customers
WHERE Fax is null
ResultSet Siralama:
Müsterilerimi ülkeye göre siraliyorum:
SELECT CompanyName,Country FROM Customers
ORDER BY Country ASC
ASC: Ascendence (küçükten büyüge)
DESC: Descendence (büyükten küçüge)
Ürünlerimi en pahalidan en ucuza dogru siralama, sonuç olarak ürün adi ve fiyatini istiyoruz:
SELECT ProductName,UnitPrice FROM Products
ORDER BY UnitPrice DESC
Ürünlerimi en pahalidan en ucuza dogru siralasin, ama stoklarini küçükten-büyüge dogru göstersin sonuç olarak ürün adi ve fiyatini istiyoruz:
SELECT ProductName,UnitPrice,UnitsInStock FROM Products
--WHERE ProductName LIKE ’C%’ de yazabiliriz..
ORDER BY UnitPrice DESC, UnitsInStock ASC
AGGREGATE FUNCTIONS (Deger döndüren fonksiyonlar. Tabloda kaç sütün var gibi..)
SELECT COUNT(*) FROM Customers
91 Tane Müsterim varmis.
SELECT CategoryID,CategoryName FROM Categories
SELECT ProductName,CategoryID FROM Products
1 Numarali kategoride kaç ürün vardir..?
SELECT COUNT(*) FROM Products
WHERE CategoryID = 1
COUNT (<KolonAdi>) : Belirtilen kolonun, ResultSet içinde kaç adet geçtigini verir.
Kaç farkli ülkeye ihracat yapiyorum..?
SELECT COUNT (DISTINCT Country) FROM Customers
DISTINCT - Tekrar edenis verme.. 3 kez Almanya geçiyorsa 1 kez göster..
Bu ülkeler hangileri..?
SELECT DISTINCT Country FROM Customers
DISTINCT: ResultSet (Uyari: ResultSet ram üzerindedir.) içinde tekrar eden verilerden YALNIZCA BIRINI alarak, bir nevi veriyi süzer.
Veri Süzme: TOP x
SELECT TOP 3 CompanyName FROM Customers
En Pahali 5 ürün dersem
SELECT TOP 5 ProductName, UnitPrice FROM Products
ORDER BY UnitPrice DESC
ALFKI CustomerID’sine sahip müsterimin siparis sayisi..?
(Orders)
SELECT COUNT(*) FROM Orders
WHERE CustomerID = ’ALFKI’
Sütun’a isim vermek için:
SELECT COUNT(*) AS ToplamSiparis FROM Orders
WHERE CustomerID = ’ALFKI’
SUM (<KolonAdi>): Belirtilen Kolonun resultset içindeki toplamini verir. Yalnizca sayisal kolonlarda kullanilabilir.
Ürünlerimin toplam maliyeti:
SELECT SUM(UnitPrice) ToplamFiyat FROM Products
Sirketim, simdiye kadar ne kadar ciro yapmis..?
Kaynak: Order Details tablosu
1-Discount (Iskontolari düseriz..
SELECT SUM (UnitPrice*Quantity*(1-Discount)) ToplamCiro FROM [Order Details]
AVG (<KolonAdi>): ResultSet içinde belirtilen kolonun ortalamasini alir:
Ortalama Ürün Fiyatim:
SELECT AVG (UnitPrice) Ortalama FROM Products
SELECT FirstName + ’ ’ + LastName as AdSoyad FROM Employees
MAX ve MIN
SELECT MAX (UnitPrice) FROM Products
SELECT MIN (UnitPrice) FROM Products
En Pahali Ürünün Adi
SELECT ProductName FROM Products
WHERE UnitPrice = (SELECT MAX (UnitPrice) FROM Products)
En az kazandiran siparis (Kaynak: Order Details)
SELECT MIN (UnitPrice * Quantity) FROM [Order Details]
Üssünü Alma:
SELECT POWER (3,2)
SELECT SQRT (81)
SELECT LEN (’DENEME’)
Müsterilerimin içinde en uzun isimli müsteri (harf sayisi)
SELECT MAX (LEN (CompanyName)) FROM Customers
SELECT GETDATE()
SELECT YEAR (GETDATE())
SELECT DAY (GETDATE())
SELECT MONTH (GETDATE())
Çalisanlarimin Ad, Soyad ve Yaslari
SELECT FirstName,LastName, YEAR(GETDATE()) - YEAR(BirthDate) as Yas FROM Employees
SELECT photo FROM Employees
GROUP BY (Gruplama)
Hangi üründen toplam kaç adet alinmis..?
SELECT ProductID, SUM (Quantity ) FROM [Order Details]
GROUP BY ProductID
Eger bir sorguda Aggregate Function ve normal bir kolon kullaniyorsaniz; o sorguda GROUP BY olmak zorundadir. GROUP BY ile baglanacak kolon ise, Aggregate Funtion disindaki tüm kolonlardir.
SELECT ProductID, SUM (Quantity ) as ToplamAdet FROM [Order Details]
GROUP BY ProductID
ORDER BY ToplamAdet DESC
Hangi sipariste toplam ne kadar kazanmisim..?
Kaynak tablo: Order Details
Istenen kolonlar: OrderID ve Kazanç (adet*fiyat)
SUM var: GROUP BY kullanmak zorundayim..
SELECT OrderID, SUM (Quantity * UnitPrice) FROM [Order Details]
GROUP BY OrderID
Hangi Kategoride toplam kaç adet ürün bulunuyor..?
SELECT CategoryID, COUNT(ProductID) FROM Products
GROUP BY CategoryID
MAX ve MIN tek deger döndürdügü için GROUP BY kullanilmaz..!
SELECT CategoryID, COUNT (ProductID) as Adet FROM Products
GROUP BY CategoryID
ORDER BY Adet
HAVING:
1000 Adetten fazla satilan ürünler:
SELECT ProductID,SUM (Quantity) As SatisAdeti FROM [Order Details]
GROUP BY ProductID
HAVING SUM (Quantity) > 1000
Bir resultset’e uygulayacaginiz kriter eger tabloda bir kolona bagliysa; WHERE kullanirsiniz. Ancak RAM’de hesaplanmis bir degere kriter uygulayacaksaniz HAVING Kullanilir..
SUB-QUERY (Alt sorgular iç içe sorgular)
Ortalamanin altinda bir fiyata sahip ürünlerimin adi ve fiyati:
1. Önce ortalamasini bulmak için bir sorgu:
SELECT AVG (UnitPrice) FROM Products
2. Bu sonucu kriter olarak kullanacak sorgu:
SELECT ProductName,UnitPrice FROMProducts
WHERE UnitPrice < (SELECT AVG (UnitPrice) FROM Products)
SELECT COUNT (*) FROM Customers
SELECT COUNT(DISTINCT CustomerID) FROM Orders
Hangi Müsterilerim hiç siparis vermemis..? (91 Müsteriden 89’u siparis vermisti..)
SELECT CompanyName,Address,City,Country FROM Customers
WHERE CustomerID NOT IN (SELECT DISTINCT CustomerID FROM Orders)
Asagidaki örnegin amaci, sub-query’nin yalnizca WHERE kriterinden sonra kullanilacagi gibi bir yanilgiyi önlemektir:
SELECT c.CategoryName + ’ (’ + CAST((SELECT COUNT (ProductID) FROM Products
WHERE CategoryID = c.CategoryID) as NVARCHAR(5) ) +’)’ FROM Categories as c
INNER JOIN
Birbiriyle iliskili tablolardan Sadece ürünü olan (ESLESEN (PRIMARY KEY ile FOREIGN KEY karsiligi olan)) kayitlardan resultset olusturan sorgu tipi:
SELECT Products.ProductName, Categories.CategoryName FROM Products
INNER JOIN Categories
ON Products.CategoryID = Categories.CategoryID
Hangi ürün hangi kategoride..
INSERT into Categories(CategoryName,Description)
values (’Tatlilar’, ’Sütlü Tatlilar’)
SELECT * FROM Categories
Hangi tedarikçi (Suppliers.CompanyName), Hangi Ürünü (Products.ProductName) Sagliyor..?
SELECT sp.CompanyName,p.ProductName FROM Suppliers as sp
INNER JOIN Products as p
ON sp.SupplierID = p.SupplierID
-- p.ProductName = Products.ProductName (Kisalttik..)
Hangi siparis (Orders.OrderID) hangi kargo sirketi ile (Shippers.CompanyName) ne zaman (Orders.OrderDate) gönderilmis..?
SELECT Orders.OrderID,Shippers.CompanyName,Orders.OrderDate FROM Shippers
INNER JOIN Orders
ON Shippers.ShipperID = Orders.ShipVia
25.11.2009. Çarsamba
hangi siparisi hangi müsteri verir..?
SELECT Customers.CompanyName,Orders.OrderID,Orders.OrderDate FROM Customers
INNER JOIN Orders
-- PRIMARY KEY -- FOREIGN KEY
ON Customers.CustomerID = Orders.CustomerID
Hangi çalisan, TOPLAM kaç siparis almis..?
-- Employees, Orders
SELECT FirstName,LastName, COUNT (OrderID) FROM Orders
INNER JOIN Employees
ON Orders.EmployeeID = Employees.EmployeeID
GROUP BY FirstName,LastName
COUNT Kullandigimiz için GROUP BY Kullandik.
En fazla siparisi kim almis..
SELECT FirstName,LastName, COUNT (OrderID) AS ToplamSiparisSayisi FROM Orders
INNER JOIN Employees
ON Orders.EmployeeID = Employees.EmployeeID
GROUP BY FirstName,LastName
ORDER BY ToplamSiparisSayisi DESC
BIRDEN FAZLA TABLO ILISKILERI
-- Hangi siparisi
-- Hangi çalisan,
-- Hangi müsteri vermistir..?
SELECT Orders.OrderID,Employees.FirstName,Employees.LastName,Customers.CompanyName FROM Employees
INNER JOIN Orders
ON Employees.EmployeeID = Orders.EmployeeID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
Hangi ürün
hangi kategoride bulunmaktadir..?
Bu ürünü kim tedarik etmektedir..?
SELECT Products.ProductName,Categories.CategoryName,Suppliers.CompanyName FROM Products
INNER JOIN Suppliers
ON Products.SupplierID = Suppliers.SupplierID
INNER JOIN Categories
ON Products.CategoryID = Categories.CategoryID
Hangi siparisi
-- hangi müsteri vermis,
-- hangi çalisan almis,
-- hangi tarihte,
-- hangi kargo sirketi tarafindan gönderilmis
-- hangi üründen kaç adet alinmis,
-- hangi fiyattan alinmis
-- ürün hangi kategorideymis
-- bu ürünü hangi tedarikçi saglamis
SELECT
Orders.OrderID,
Customers.companyName,
Employees.FirstName+ ’ ’ + Employees.LastName as Calisan,
Orders.OrderDate,
Shippers.CompanyName as Kargo,
Products.ProductName,
[Order Details].Quantity,
[Order Details].UnitPrice * (1-[Order Details].Discount) as indirimliFiyat,
Categories.CategoryName,
Suppliers.CompanyName as Tedarikci
FROM Employees
INNER JOIN Orders
ON Orders.EmployeeID = Employees.EmployeeID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
INNER JOIN Shippers
ON Shippers.ShipperID = Orders.ShipVia
INNER JOIN [Order Details]
ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Products
ON Products.ProductID = [Order Details].ProductID
INNER JOIN Categories
ON Categories.CategoryID = Products.CategoryID
INNER JOIN Suppliers
ON Suppliers.SupplierID = Products.SupplierID
OUTER JOIN
SELECT * FROM Categories
INSERT into Categories(CategoryName,Description) values
(’Tatlilar’, ’Hede Hödö’)
Altinda ürün bulunmayan kategoriler
SELECT Categories.CategoryName,Products.ProductName FROM Products
RIGHT JOIN Categories
ON Products.CategoryID = Categories.CategoryID
WHERE ProductName is null
91 müsterim var. Sadece 89’u siparis vermis. Siparis vermeyen 2 kisiyi bulun:
SELECT CompanyName,Address,OrderID FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
WHERE OrderID is null
LEFT veya RIGHT kelimesi tamamini getirmek istediginiz tablonun Join kelimesinin neresine yazildigi ile ilgilidir.
JOIN kelimesinin solundaki tablonun tüm kayitlarini getirmek için LEFT,
Sagindakini getirmek için ise RIGHT kelimesini kullanirim.
Daha önce asagidaki sekilde bulmustuk..
Hangi Müsterilerim hiç siparis vermemis..? (91 Müsteriden 89’u siparis vermisti..)
SELECT CompanyName,Address,City,Country FROM Customers
WHERE CustomerID NOT IN (SELECT DISTINCT CustomerID FROM Orders)
HANGI ÇALISAN SIMDIYE KADAR TOPLAM KAÇ SIPARIS ALMIS..?
-- iki farkli (bagimsiz) sorgu var.
SET STATISTICS TIME ON
SELECT EmployeeID,FirstName,LastName,
(SELECT COUNT (orderID) FROM Orders WHERE EmployeeID = x.EmployeeID)
FROM Employees as x
UNION (2 farkli resultset’i birlestirir.)
-- iki ya da daha fazla tabloyu birlestirir..
-- Kural: iki resultset içindeki kolonlar ayni sayida ve sirasiyla ayni tipte olmalidir. (int-string alt alta olmaz..)
SELECT CompanyName,Address,City,Country, ’ Müsteri’ FROMCustomers
UNION
SELECT CompanyName,Address,City,Country, ’ Tedarikçi’ FROMSuppliers
ORDER BYCountry
01.12.2009.SALI
SET STATISTICS TIME ON
SELECT Products.ProductName, Products.UnitPrice, Categories.CategoryName,Categories.Description FROM Products
CROSS JOIN Categories
CROSS JOIN Tüm iliskili-iliskisiz (LEFT JOIN, RIGHT JOIN, INNER JOIN, OUTER JOIN)Tablolari Görmemizi saglar. Sadece süre olarak ne kadar sürede sorgu çekildigini hesaplamamiza yardimci olur.
CHECK ve DEFAULT Constraintler
use Normalizasyon
ALTER TABLE Urunler
ADD CONSTRAINT DF_AktifMi
DEFAULT 1 for AktifMi
Products için yapsaydik DF_Discontinued - for Discontinued olacakti...
CHECK
ALTER TABLE Urunler
ADD CONSTRAINT CK_Fiyat
CHECK (Fiyati > -1)
Artik ürünler tablosuna eksi bir deger giremeyecegiz..
INDEX
use Northwind
GO
SELECT ProductName,UnitPrice FROM Products
WHERE ProductID = 1
SELECT * FROM Customers
WHERE Country = ’Germany’
Almanya’da bulunan müsterim
-- Hangi kolonu indexlemem lazim.. Burada Ülke’yi index’lersek "Germany" ’yi sadece ülkelerde arayacak.
CREATE Nonclustered INDEX ix_Ulke
ON Customers(Country)
Sorgular, bosluklardan sonra yavaslar. 3-6 aylik bakimlarda index temizlemek gerekebilir...
DBCC INDEXDEFRAG
DROP INDEX deyip yeni INDEX Olusturmak
SELECT * FROM Northwind.dbo.Products
FQN: FULLY QUALIFIED NAME: UZUN KÜNYE (Sunucudan Kolon Adina Kadar Tüm Nesneleri Nokta Ile Birlestiren Object Adi):
--Örnek:<sunucuAdi>.<veritabaniAdi>.<semaAdi>.<tabloAdi>.<kolonAdi>
FQN Master ile Sunucuma bagli (ya da tanimli) diger sunucularima sorgu çekebilmemi saglar..
Sunucu adi yerine IP Numarasi da yazabiliriz...
CREATE VIEW UrunlereGoreTedarikciler
AS
SELECT ProductName,companyName,Address,City,Country FROM Products
INNER JOIN Suppliers
ON
Products.SupplierID = Suppliers.SupplierID
View yaratmadan önce sorgunun çalisip-çalismadigi mutlaka kontrol edilmelidir..
SELECT * FROM UrunlereGoreTedarikciler
Sonuçta tablo olduguna göre WHERE kriteri de kullanabiliriz..
WHERE CompanyName LIKE ’E%’
ORDER BY Country
SELECT * FROM tumSiparisDetaylari
WHERE OrderID = 10248
ORDER BY ProductName
Hangi durumlarda view içine INSERT Yapilamaz:
1. Eger, View, INNER JOIN içeriyorsa (Arkada bisürü tablo var, hangisini yapacagini bilemiyor)
2. View sonucunda olusacak resultset’deki tüm kolonlar bos geçileez ise
3. CHECK OPTION seçenegi ile view olusmussa
CREATE VIEW AlmanMusteriler
AS
SELECT CustomerID,CompanyName,Address,City,Country FROM Customers
WHERE Country = ’Germany’
INNER JOIN içermiyor, bos geçilemez (not null) alan da var o zaman view a uyuyor. (ilk iki kosulu sagladi)
WITH CHECK OPTION
Insert sirasinda gelen kaydi kontrol et, eger uyuyorsa kabul et..
SELECT * FROM AlmanMusteriler
INSERT into AlmanMusteriler(CustomerID,CompanyName,Address, City,Country)
values
(’ACTHU’,’ACHTUNG Co.’,’Hede’,’Berlin’,’Germany’)
Burada Türkiye yazmis olsaydik insert into yapamazdik. Çünkü where kriteri Germany olarak aldik. Eger where kriteri koymamis olsaydik bu sefer de CHECK OPTION a gerek kalmazdi..
WITH CHECK OPTION: Bir view nesnesine, INSERT ya da UPDATE sorgusu çalistiginda, yeni gelen datanin view kurallarina uymasini istiyorsak; CHECK OPTION seçenegini kullanabiliriz.
Sifrelemek istiyorsak; with encryption kullaniriz.. Sifreledikten sonra biz bile göremiyoruz..
CREATE VIEW UrunBilgisi
with Encryption
AS
SELECT ProductName,UnitPrice FROM Products
INJECTION
SELECT * FROM Users WHERE KullaniciAdi = ’’ ANDSifre = ’’
Normalde Sifre mantigi yukaridaki gibidir.. o halde asagidaki sifreyi kirar.
SELECT * FROM Employees WHERE FirstName = ’’ OR’A’=’A’ AND LastName=’’ OR ’A’=’A’
’ or ’A’=’A
SCHEMABINDING
SCRIPT ve BATCH
Degiskenler
DECLARE @Sayi int
Degiskenin degerini ben veriyorsam:
SET @Sayi=5
Print(@Sayi)
DECLARE @CalisaninAdi nvarchar(20)
Degiskenin degerini bir sorgu araciligi ile gelecekse:
SELECT @CalisaninAdi = FirstName FROM Employees
WHERE EmployeeID = 1
Print(@CalisaninAdi)
DECLARE @x int
SET @x=8
Print(’Sayi = ’+
CAST(@x as nchar(2))
)
x’i al 2 karakterli nchar’a çevir.
DECLARE @x int
SET @x=8
Print(’Sayi = ’+
CONVERT(nchar(2),@x)
)
x’i al 2 karakterli nchar’a çevir.. (Yukaridaki ile tamamen ayni)
Bir siparis girdigim anda, olusan SON ORDERID bilgisini nasil elde ederim..?
SELECT TOP 1 OrderID FROM Orders
ORDER BY OrderID DESC
Bunu Degisken atmak istersem;
DECLARE @ID int
SELECT TOP 1 @ID=OrderID FROM Orders
ORDER BY OrderID DESC
Print(@ID)
INSERT into Orders(CustomerID,EmployeeID,OrderDate,ShipVia)
values (’ALFKI’,’1’,GETDATE(),1)
SELECT @@IDENTITY
Global Degisken @@
Herhangi bir user, global sql degiskeni TANIMLAYAMAZ
INSERT into Orders(CustomerID,EmployeeID,OrderDate,ShipVia)
values (’ALFKI’,’1’,GETDATE(),1)
SELECT @@IDENTITY
SELECT SCOPE_IDENTITY()
WHEN / CASE:
SELECT CompanyName,Region =
CASE
WHEN Region = ’BC’ THEN ’Washington’
WHEN Region = ’SP’ THEN ’Pensilvanya’
WHEN Region = ’OR’ THEN ’Orlando’
END
FROM Customers
WHERE Region is not null
SELECT ProductName,Discontinued=
CASE
WHEN Discontinued = ’0’ THEN ’Satis Durduruldu’
WHEN Discontinued = ’1’ THEN ’Satis Devam Ediyor’
END
FROM Products
TRY – CATCH
BEGIN TRY
SELECT 1/0
END TRY
BEGIN CATCH
SELECT ERROR_Message()
END CATCH
STORED PROCEDURE (SAKLI YORDAM) ---
CREATE PROC KategoriGetir
AS
SELECT * FROM Categories
KategoriGetir
CREATE PROC IDyeGoreUrun
@id int
AS
SELECT ProductName,UnitPrice,UnitsInStock FROM Products
WHERE ProductID = @id
IDyeGoreUrun 77
ID si 77 olan ürünün bilgisini getiriyor..
Normalde Ürün eklerken su sekilde islem yapariz..
INSERT INTO Categories (CategoryName,Description)
values (@KategoriAdi,@Aciklama)
Stored Procedure Yapalim..
CREATE PROC KategoriEkle
@KategoriAdi nvarchar(15),
@Aciklama ntext
AS
INSERT INTO Categories (CategoryName,Description)
values (@KategoriAdi,@Aciklama)
KategoriEkle ’Unlu Mamüller’, ’Türk Usulü Unlu Börek Çörek’
ÖDÜLLÜ ÖDEV: Yapan Herkese Çikolata... ;)
ID’si verilen müsterinin toplam ne kadarlik alisveris yaptigini (fiyat olarak) bulan procedure
SELECT SUM ([Order Details].UnitPrice*Quantity*(1-Discount))
FROM [Order Details]
INNER JOIN Orders
ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
WHERE Customers.CustomerID = ’ALFKI’
Önce burasi çalisiyor mu kontrol edelim ve
Simdi Procedure i olusturalim
CREATE PROC MusterininAlisVerisi
@ID char(5)
AS
SELECT SUM ([Order Details].UnitPrice*Quantity*(1-Discount))
FROM [Order Details]
INNER JOIN Orders
ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
WHERE Customers.CustomerID = ’ALFKI’
MusterininAlisVerisi ’OCEAN’
SELECT CustomerID FROM Customers
Çesitlendirmek mümkün...
CREATE PROC MusterininAlisVerisi2
@ID char(5)
AS
SELECT SUM ([Order Details].UnitPrice*Quantity*(1-Discount)) AS Toplam
FROM [Order Details]
INNER JOIN Orders
ON Orders.OrderID = [Order Details].OrderID
INNER JOIN Customers
ON Customers.CustomerID = Orders.CustomerID
WHERE Customers.CustomerID = @ID
GROUP BYCustomers.CustomerID,CompanyName
ORDER BY Toplam DESC
MusterininAlisVerisi2 ’QUICK’
SELECT CustomerID FROM Customers
iki tarih araliginda bulunan siparisler:
SELECT OrderID,OrderDate,ShipAddress FROM Orders
WHERE OrderDate BETWEEN ’31/12/1996’ AND ’15/07/1997’
Simdi procedure olusturalim..
CREATE PROC TariheGoreSiparis
@Tarih1 smalldatetime,
@Tarih2 smalldatetime
AS
SELECT OrderID,OrderDate,ShipAddress FROM Orders
WHERE OrderDate BETWEEN @Tarih1 AND @Tarih2
TariheGoreSiparis ’01/01/1997’, ’06/06/1997’
Yila Göre Ciro
CREATE PROC YilaGoreCiro
@Yil int
AS
SELECT SUM (Quantity * UnitPrice * (1-Discount)) FROM [Order Details]
INNER JOIN Orders
ON Orders.OrderID = [Order Details].OrderID
WHERE YEAR (Orders.OrderDate) = @Yil
YilaGoreCiro 1997
ID si verilen müsteri, en son hangi ürünü almis..?
ID si verilen çalisan, en çok kime ürün satmis..?
ID si verilen müsteriyle ne kadar süredir çalisiyoruz..?
ID si verilen kategorinin içinde en çok satan 5 ürün..?
ID si verilen tedarikçi bana hangi ürünleri sagliyor..?
CREATE PROC HangiUrun
@ID char(5)
AS
SELECT TOP 1 Customers.CompanyName,Products.ProductName,[Order Details].Quantity,Orders.OrderDate FROM Customers
INNER JOIN Orders
ON Customers.CustomerID = Orders.CustomerID
INNER JOIN [Order Details]
ON Orders.OrderID = [Order Details].OrderID
JOIN Products
ON [Order Details].ProductID = Products.ProductID
WHERE Customers.CustomerID = @ID
ORDER BY Orders.OrderDate DESC
HangiUrun ’QUICK’
-- Tabloda iliskili olanlara baktik.
Flash Disk Alanlar.
SELECT FROM
1. Sadece o ürünün bulundugu siparisler:
CREATE PROC BunuAlanBunudaAldi
@productID int
AS
SELECT TOP 5 ProductName, SUM(Quantity) as toplam FROM Products
INNER JOIN [Order Details]
ON Products.ProductID = [Order Details].ProductID
WHERE
[Order Details].OrderID
IN
(
SELECT OrderID FROM [Order Details]
WHERE ProductID=@productID
)
AND [Order Details].ProductID !=@productID
GROUP BY ProductName
ORDER BY toplam DESC
BunuAlanBunudaAldi 9
FONKSIYONLAR
ÜRÜNLER TABLOSUNDAKI TÜM FIYATLARIN KDV’SINI HESAPLASIN
PROCEDURE
HERHANGI BIR DEGERIN KDV’SINI HESAPLASIN dersek, FONKSIYON OLUR.. Herhangi bir tabloya bagli kalmadan..
CREATE FUNCTION KDVHesaplayici
(
@Para money
)
RETURNS money
AS
BEGIN
DECLARE @Deger money
SET @Deger= @Para * 1.18
RETURN @Deger
END
SELECT ProductName,UnitPrice, dbo.KDVHesaplayici(UnitPrice) AS KDVDahil
Fonksiyon, her zaman semaya bagli çalisir
FROM Products
Parametre olarak girilen int bir sayinin karesini alalim..
CREATE FUNCTION KaresiniAl
(
@Sayi int
)
RETURNS int
AS
BEGIN
DECLARE @Sonuc int
SET @Sonuc= @Sayi * @Sayi
RETURN @Sonuc
END
SELECT dbo.KaresiniAl(9)
VEYA
CREATE FUNCTION KaresiniAlalim
(
@x int
)
RETURNS int
AS
BEGIN
RETURN @x*@x
END
SELECT dbo.KaresiniAlalim(9)
AliAKYILDIRIM
SELECT UPPER (’ali’)
SELECT LOWER (’AKYILDIRIM’)
SELECT LEN (’Dilek’)
SELECT SUBSTRING (’AliAKYILDIRIM’,1,5)
CREATE FUNCTION ParafOlusturucu
(
@Ad nvarchar(50),
@Soyad nvarchar(50)
)
RETURNS nvarchar(100)
AS
BEGIN
DECLARE @donenDeger nvarchar(100)
SELECT @donenDeger = UPPER(SUBSTRING(@Ad,1,1))+’.’+
UPPER(SUBSTRING(@Soyad,1,1)) +
LOWER(SUBSTRING(@Soyad,2,LEN(@Soyad)))
RETURN @donenDeger
END
SELECT dbo.ParafOlusturucu(’Ali’,’Akyildirim’)
SELECT TitleOfCourtesy + ’ ’ + dbo.ParafOlusturucu(FirstName,LastName)
FROM Employees
IKI TÜRLÜ FUNCTION VARDIR; IN-LINE FUNCTION ve MULTI-LINE FUNCTION.
ADINDAN ANLASILDIGI GIBI, IN-LINE FUNCTION ICINDE YALNIZCA TEK SATIR VARDIR. BU DURUMDA BEGIN/END YAPISINI KULLANMAK ZORUNDA DEGILSINIZ. ANCAK MULTI-LINE (COK SATIRLI) BIR FUNCTION BEGIN ILE BASLAYIP END ILE BITMEK ZORUNDADIR.
CREATE FUNCTION ResultSetOlustur
()
RETURNS TABLE
AS
RETURN SELECT CompanyName, Country FROM Customers
SELECT * FROM dbo.ResultSetOlustur()
TRANSACTION
BEGIN TRY
END TRY
BEGIN CATCH
END CATCH
-- KALIP BU
BEGIN TRY
Begin Tran
Insert, Update ya da Delete sorgusu transaction içinde kullanilabilir
commit tran
END TRY
BEGIN CATCH
END CATCH
Adim Adim Nasil yazildigina bakalim..
BEGIN TRY
Begin Tran T1
-- Insert, Update ya da Delete sorgusu transaction içinde kullanilabilir
Begin Tran T2
-- Bir sorgu daha (Önce T1 çalisir sonra T2)
commit tran
commit tran
END TRY
BEGIN CATCH
-- Hata olusursa, tüm transaction’i geri al:
ROLLBACK TRAN T1
END CATCH
BEGIN TRY
BEGIN TRAN KategoriEkle
insert into Categories(CategoryName,Description)
values (’Ayakkabi’,’Kislik/Yazlik Bay/Bayan’)
Begin Tran UrunSil
DELETE FROM Products WHERE ProductID=1
commit tran
commit Tran
END TRY
BEGIN CATCH
ROLLBACK TRAN KategoriEkle
END CATCH
Veri güvenligi açisindan, eger execute edilecek sorgulama mantigi birbiriyle ardisik olmasi gerekiyorsa:
(Örnek: Önce Siparis Ekle, Sonra siparis detaylarina gidip adet ekle sonra ürünler tablosundan stok düs)
Mutlaka transaction blogu kullanin!
* DIPNOT: Transaction blogunu kullanmak için en elverisli ortam stored procedure’lerdir.
TRIGGER (INSERT, UPDATE, DELETE Sorgusundan Sonra Tetikler)
SIPARIS ALINDIGINDA ÜRÜNDEN STOK DÜSEN TRIGGER’I YAZALIM.
CREATE TRIGGER tr_OtomatikStok
ON [Order Details]
for INSERT
-- INSERT SORGUSUYLA ÇALIS , INSERT SORGUSUYLA BIRLIKTE TETIKLEN
AS
-- Amaç: Order Details Tablosuna kayit girildiginde, ilgili ürünün stok bilgisini Products Tablosundan bulup, adet kadar azaltsin.
DECLARE @UrunID int
-- Bir degisken tanimladik
DECLARE @Adet int
-- Adet kadar azaltacagi için Adet adli bir degiskenimiz olmali..
-- Her Tabloya bagli iki adet geçici tablo vardir. Bu tablolara Trigger disindan ulasilamaz. inserted ve deleted ismindedirler.
-- INSERTED; INSERT Sorgusundan sonra olusacak satir, önce INSERTED geçici tablosunda bekletilir.
-- DELETED; Silinmeye çalisilan satir, silinmeden önce DELETED geçici tablosunda bekletilir.
SELECT @UrunID = ProductID, @Adet = Quantity
FROM INSERTED
UPDATE Products SET UnitsInStock = UnitsInStock-@Adet
WHERE ProductID = @UrunID
-- Trigger i olusturduktan sonra asagidaki sorgulari yaptigimda otomatik olarak güncellenecektir.
INSERT into [Order Details](OrderID, ProductID, Quantity)
values (10323, 1, 2)
SELECT ProductName,UnitsInStock FROM Products
WHERE ProductID = 1
-- ihtiyaç: Products tablosundan ürün silinmeye çalisildiginda bu ürünün Discontinued kolonunu 1 yapsin (Yani Silmesin, Update etsin):
CREATE TRIGGER tr_SatisiDurdur
ON Products
INSTEAD OF delete
-- Delete ’in çalismasina izin vermeden trigger çalissin
AS
-- INSTEAD OF ’larin tamami BEGIN - END içinde yazilir...
-- Silmeye çalistigim ürünün Discontinued ’ini 1 yapacagim:
BEGIN
DECLARE @UrunID int
SELECT @UrunID = ProductID FROM deleted
UPDATE Products SET Discontinued = 1
WHERE ProductID = @UrunID
END
SELECT * FROM Products WHERE ProductID = 1
DELETE FROM Products WHERE ProductID = 1
INSTEAD OF TRIGGER ’lar tetikleyici sorgunun YERINE çalisirlar. Ayirdedici tek özellikleri ise BEGIN END satirlari arasina yaziliyor olmasidir.
ÖRNEK VERITABANI - TRIGGER IÇIN
CREATE TABLE Ogrenciler
(
OgrenciNo int,
Ad nvarchar(50),
Soyad nvarchar(50),
DersNotu tinyint
)
GO
-- GO: BIR SONRAKI ADIMA GIT DEMEKTIR
--CREATE TABLE Gecenler
--(
--OgrenciNo int,
--Ad nvarchar(50),
--Soyad nvarchar(50),
--DersNotu tinyint
--)
--GO
--CREATE TABLE Kalanlar
--(
--OgrenciNo int,
--Ad nvarchar(50),
--Soyad nvarchar(50),
--DersNotu tinyint
--)
Ders Notu 50 den küçükse kalanlara kaydet, 50 den büyükse Geçenlere kaydet.. Kendisi karar versin.
--CREATE TRIGGER tr_KararVer
--ON Ogrenciler
--FOR INSERT
--AS
--DECLARE @No int
--DECLARE @Ad nvarchar(50)
--DECLARE @Soyad nvarchar(50)
--DECLARE @DersNotu tinyint
--SELECT @No=OgrenciNo, @Ad=Ad, @Soyad=Soyad, @DersNotu=DersNotu
--FROM INSERTED
---- INSERTED Geçici tablusunda sadece 1 satir var..
--IF @DersNotu <50
-- INSERT into Kalanlar values (@No,@Ad,@Soyad,@DersNotu)
--ELSE
-- INSERT into Gecenler values (@No,@Ad,@Soyad,@DersNotu)
--INSERT into Ogrenciler values (1, ’Ali’, ’Veli’, 80)
--SELECT * FROM Ogrenciler
--SELECT * FROM Gecenler
--INSERT into Ogrenciler values (1, ’Ali’, ’Akyildirim’, 40)
--SELECT * FROM Ogrenciler
--SELECT * FROM Kalanlar
-- GÜVENLIK ve PERFORMANS..
-- DBCC KOMUTLARI
DBCC ShowContig (’Customers’)
-- Veritabaninda kullanilan tablolarin performans detaylarini getiren güzel bir komuttur..
--- 08.12.2009.Sali ---
Yedek Alma Kodu
ALTER DATABASE Northwind
SET RECOVERY FULL
-- Yedek aldigim yer çogu zaman ayni ise, bu yeri SQL’e kaydedebilirim. Sart degildir. Kullanim kolayligidir.
-- system procedure (sp)
-- SQL Kendi kendine yedek alirken klasör olusturamaz. Bu nedenle C’de Yedek isimli bir klasör olustur ve ardindan backup islemini yap..
sp_addumpdevice ’DISK’, MyDevice , ’C:\Yedek\NWFull.bak’
SELECT * FROM sys.backup_devices
BACKUP DATABASE Northwind TO MyDevice
Device’siz yedek alma ise;
BACKUP DATABASE Northwind TO DISK = ’C:\Yedek\NWManuel.bak’
-- Back up i periyodik olarak almak gerekir. Peki, pzt aldigim yedegi sali günü tekrar almak yerine aradaki farki backup almak istersem, Differencial Backup kullanmam gerekir.
INSERT into Northwind.dbo.Products (ProductName,UnitPrice)
values (’Dondurma’,5)
BACKUP DATABASE Northwind TO DISK = ’C:\Yedek\NWFark.bak’
WITH DIFFERENTIAL
-- Transaction Log neden temizlenmeli..? INSERT, UPDATE, DELETE sorgularinin
çalismalari durumunda, hangi sorgunun ne zaman çalistigi ve nasil islem
yaptigi .ldf uzantili db dosyasinda tutulur. Biz bu sorgulari
her çalistirdigimizda log dosyasina islenecektir. Bir süre sonra
log dosyalari asiri sisme göstereceginden, bu tarz sorgularin çalisma
hizi düsecektir. Bu hizi tekrar yükseltmek için tek yapmak gereken LOG BACKUP almaktir.
LOG Dosyasini Backup Yapalim.
UPDATE Northwind.dbo.Products SET UnitPrice = 10
WHERE ProductID = 81
BACKUP LOG Northwind TO DISK = ’C:\Yedek\LogDosyasi.bak’
Her GÜZEL SEYIN BIR SONU VARDIR: ;-)
DROP DATABASE Northwind
-- ama bazi seyler geri alinabilir:
RESTORE DATABASE Northwind FROM DISK = ’C:\Yedek\NWFull.bak’ WITH NORECOVERY
RESTORE DATABASE NorthwindFROM DISK = ’C:\Yedek\NWFark.bak’ WITH NORECOVERY
RESTORE LOG Northwind FROMDISK = ’C:\Yedek\LogDosyasi.bak’ WITH RECOVERY
WITH NORECOVERY ve WITH RECOVERY Farki;
-- Yedeklemenin belirli bir sirasi var. Hepsini birden çalistiracagiz ancak Full ve Differential olanlari beklet en son LOG la beraber RECOVERY yap.
Kaynak: Bu Örnek, Bilge Adam egitimi Sirasinda Türkay Ürkmez Tarafindan Yapilmis ve Yazilimcik.com ailesi tarafindan gelistirilmistir.