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/1996AND31/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.