MS SQL Ve ORACLE Ile Veritaban Programlama

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 77

Ders Eitmen: Notlar tutan

: MS SQL ve ORACLE ile Veritaban Programlama : Hseyin Bte : Berk Acuna CMLE

NOT: DERS NOTLARINDA HIZLI NOT ALMAKTAN KAYNAKLANAN DKLKLER, MLA HATALARI VE HATALI BLGLER BULUNABLR.

5 Temmuz 2008 ANA BALIKLAR 1. Veritaban nedir ? DBMS nedir ? 2. Veri modelleme, normalizasyon nedir ? 3. Veritaban oluturulmas a) Tablolarn oluturulmas, ynetimi (yetkiler, tablo yapsnda deiiklik, kstlar (constraint) b) Tablodaki veriler zerinde ilemler (INSERT, DELETE, UPDATE, SELECT) c) Birden fazla tabloda ilemler (JOIN) d) Grnmler e) Programlama nesneleri (fonksiyonlar, stored procedures, triggers) 4. Gvenlik 5. Yedekleme 6. Scheduled Jobs 7. Replikasyon 8. Program TARHE ve MMARLER 1970 - ORACLE, DB2 Mainframe'ler ortaya kyor. (MainFrame = Tek bir makina. ok sayda klavye ve monitr) 1971 IBM aratrmacs Dr. Codd, Relational Modeli ve standartlarn ortaya konuyor. (Gnmzde kullanlan DB mimarileri bu model ve standartlar kullanmaya devam etmektedir.) Bundan sonra relational db'ler ortaya kyor. Tablosal bir yapda DB'ler tutulmaya balanyor. (Relational model'deki relational deyimi tablolar arasndaki ilikileri belirtmek iin kullanlan relational deyiminden farkldr. Burada, Relational deyimi ile veritabannn tablolardan olumas, "tabular" bir yapda bulunuyor olmas anlatlmak istenmektedir.) 90'lar ile birlikte PC'lerde almak iin tasarlanan Fileshare mimarisi ile alan dBase, Paradox, Access gibi RDBMS'ler kyor. Bu dnemde network'lerde ortaya kyor ve .mdb file share edilmi halde bir makinada duruyor, bir klasr ya da dosya share etmi, ve dier makinalarda bir akll, asl ii yapan client DB program var, server'daki dosyay paylamdan alp kullanyorlar. Bunun dezavantaj byk, nk programlar tm client'lara kurulmal, ayrca farkl client'lar server'a eriirken defalarca server'a gidip geliyor ve bu da network trafii oluturuyor. 10 makinada belki iyi ama daha fazlas kt. Ayrca server'daki db dosyas tam yetki ile paylatrlyor. (Temel problemi yava olmas - WAN'da performans asndan ok yava) (Bu mimari Fileshare mimarisi - client server deil) Bundan sonrasnda client - server mimarisi ortaya kt. Sunucuda bir server yazlm var ve client'larda herhangi bir program olabilir. DB'nin kendisi gene sunucuda. Ancak bu mimaride client'lar akll deil, gidip server'dan talepte bulunuyor. SQL Server talebi alyor ve cevap veriyor. Bu alma yntemi ile

FileShare mimarisinin eksilerinin stesinden gelindi. (FileShare mimarisinde ana makina yalnzca dosyay paylatrr, baka ilevi yoktur.) nce MainFrame bir sr ekran ve klavye ile ynetiliyordu. Sonra, PC'lerin yaygnlamas ile network'ler ortaya kyor ve ilk network kurma tr olarak FileShare mimarisi ortaya kt. FileShare mimarisinin yetersiz kalmas ile ClientServer mimarisi ortaya kar. Client - Server mimari bir kademe ilerledi: Client ile server arasnda artk bir application server var. Web sunucusu gibi. rnein internet ile ilgili bu mimarinin kullanmnda tm client'lara client program kurulamayacana gre client browser'a sahiptir ve bununla web server'a eriir. Buna da web based mimari denilmektedir.

RELATIONAL DATABASE Relational DB'nin tesinde ne var ? Eksikleri nelerdir ? 1) En byk eksikleri nesne yapsnda olmamalar. Gnmzde Object Oriented yazlmlar gelitirilmekte. Uygulama kodunda ilgili tablo bir class ile temsil edilmek zorunda. Yani, yazdmz programda tabloya karlk gelen class'ta tablodaki field'ler snfn birer field'i olarak temsil edilir ve bundan sonraki ilemler zahmetlidir. Mesela bir stok tablosu 100'lerce kolondan oluabilir ve DB'deki field'lerin kstlarn nesnenin field'lerinde de gerekletirmemiz gerekir. Bu problem iin gnmzde birtakm mapping aralar kullanlmaktadr. 2) Bir dier problem programlama dilindeki veri tr ile DB'nin veri trleri uyumayabilir. zetle Relational Model'de tabloyu uygulama koduna tamakta problemler yaanabilir. LinQ ve Hybernate bu konuda kullanlan mapping aralardr. Ayrca, son olarak DB'nin yaps deiirse onunla bal uygulama kodunun da deitirilmesi gerekir. 3) Relational DB'de tablolarda inheritence kullanlamyor. Mesela bir taban tablodan treyen alt-tablo yaplamyor. Bu yap gerekletirilemedii iin bir ok tabloda ilem yaplacanda anlalabilirlii drmeyi gze alarak JOIN'lerle tablolar birletirip ilem gerekletirmekteyiz. Relational DB'nin eksikleri iin OODBMS'ler (Object-Oriented Database System) gelitirilme srecindedir. Ancak, bu sistem gnmzdeki RDBMS'lerin yapsn karlamyor yani backward deil. Bunun iin gnmzde ORDBMS'ler (ObjectRelational Database Management System) kullanlabilmektedir. DB'ler nceden Visio gibi bir programla tasarlanr. (ve Rational Rose gibi, srklebrak ile ilikiler vb... grsel olarak tasarlanr.) Start > Programs > MSSQL 2005 ile asl kullanacamz ara alr. Databases'n zerine Sa tkla new db'yi se. Ya da, Create database dbName ve F5 ile altr. Bir database'i silmek iin DROP database dbName Object Explorer'dan Tables'a git. Sa tkla New Table' se. lk olarak bir Stok tablosu yapacaz. Tablolarda isimler genelde tekil olarak kullanlr. Stoklar deil stok tablosu gibi. Peki stoktaki alanlar ne olacak: ncelikle her bir satr tanmlayan unique bir bilgi ieren bir alan olmaldr. Bu alana primary key alan denir. Sonra, stok kodu rnein firma tarafndan retilmise bu kod primary key olarak kullanlabilir. (StokAdi pek uygun deil) Peki, eer primary key bir string

deer ise performans kayb olacaktr, bunun yerine int bir deer kullanmak performans belirgin ekilde artracaktr. [Ancak, kullanabileceiniz stok kodu gibi bir unique deer varsa int bir primary key deeri kullanmak yerine bu string deeri kullann nk SQL sorgusunu oluturmak ok daha kolay olacaktr: SELECT * FROM Stok WHERE StokKod = 'RAM256' Burada, RAM256 bir primary key'dir. Primary key olarak int bir id'nin mi yoksa stok kodu gibi bir string deerin kullanlmas arasnda bir genel kabul yoktur. kisinin de eksi ve artlar vardr. string primary key performans drr ancak tabloya ayrca int bir primary key eklersek, normalization bize gerek olmayan bir alan yaratmayn der. - Hseyin Hoca ve snf tartmas] == Genel fikir kullanm amacna gre karar vermek gerekir. Primary key hi bir zaman deimeyecek ve unique bir deer olmak zorundadr.

Stok tablosu: Stok [lk harf byk, birden ok kelimeden oluuyorsa Pascal notasyonu tercih edilir.] Kolon isimlendirmede sadece Kod demiyoruz, StokKod diyoruz, unique, auto increment int primary id'ler iin ise StokId gibi. StokKodu ya da StokAdi demiyoruz, StokKod ve StokAd diyoruz. [Stok] - StokKod - Char(10) - Allow Null deil - Primary Key (Oracle'clar STOK_KOD eklinde bir konvensiyon kullanyor. MS ise PASCAL kullanyor.) - StokAd - VarChar(100) - Allow Null deil - Aciklama - VarChar(500) - Allow Null - Miktar - Integer - Allow Null deil - KDV - Integer - Fiyat - Decimal(8 ,2) // Hane says [--Bitti--] Char(10) ile VarChar(10) arasndaki fark nedir ? Char(10) sabit yer ayrr. Programc buraya 4 karakterlik veri girse de 10 karakter yer gider. VarChar(10)'da ise en fazla 10 byte olabilir diyoruz, eer 4 karakter kullanrsak 4 karakter gider. Ne zaman Char ne zaman VarChar kullanlmal ? Char daha ok yer gtryor ancak VarChar'a gre daha hzl alr. nk, bir veriyi VarChar'a yazarken ka karakter yazd ile ilgili okuma ilemi yapar, bu da VarChar' Char'a gre daha yava yapar. Numeric tr ile Decimal tr ayndr. Para deerini decimal'de tutmamz gerekir. nk decimal tr otomatik yuvarlama yapmaz. Kayan noktal trler kendi kafasna gre yuvarlama yapabilirler ve bu para mevzusunda istenen bir durum deildir. Bu sebeple numeric/decimal alan kullanlr. ABD'de para konusunda virglden sonra 4 hane tutulur, bunun iin decimal'in virglden sonra 4 hane tutan hali olarak money tr kullanlr. DB > Programmatibility > Types > System Data Types'tan DBMS'nin kulland veri trleri grntlenebilir.

Stok tablosuna veri ekleme: [rnekler] INSERT Stok VALUES ('RAM256', '256 SD RAM', null, 36, 18, 46) SELECT * FROM Stok INSERT Stok VALUES ('RAM512', '512 SD RAM', null, 6, 18, 66) INSERT Stok VALUES ('DSK80', '80 GB HDD', null, 6, 32, 166) INSERT Stok VALUES ('DSK160', '160 GB HDD', null, 16, 132, 16) DELETE FROM Stok WHERE StokKod = 'RAM256' MS SQL Server programnda bir query yazma ekrannda birden fazla query yazarsak fakat bunlardan yalnzca birinin almasn istersek almasn istediimizi tarayp F5 ile query'yi altrmalyz. Bylece, yalnzca taranan query altrlr. Kolon isimlerinde eer boluk kullanrsak sorgu yazarken bu kolon adn keli parantez ierisinde yazmamz zorunludur. Hatal bilgi girdiysek UPDATE etmemiz gerekir: UPDATE Stok SET Miktar = 16 WHERE StokKod = 'RAM256' 6 Temmuz 2008 Relational DB terimi, tablolar arasndaki ilikilerden ok bir veritabannn verilerini tablolarda tutuyor olmasn ifade eder. simlendirme konvensiyonu olarak Viewler iin vw_viewname ve procedureler iin up_procedureName (up = user procedure) kullanlabilir. null != 0 (int iin) [null demek int tr iin 0 demek deildir] null != (string iin) [null demek string tr iin bo string demek deildir] Relational teoriye gre alanlar allow null olmamaldr. USE SQLHelloSample => Belirtilen DB'ye geer. Query'de Primary Key oluturmak iin: CONSTRAINT pk_StokKod PRIMARY KEY(StokKod) Burada girilen pk_StokKod ismi rnein alma zamannda bir problem olutuunda diagnostik olarak bu isim kullanlr. PK'lere gre tablolar indekslenir. ndekslenme sayesinde sral arama yerine BTree veriyapsnda tutulan data ok daha hzl bulunur. (Logaritmik karmaklk) PK'sz tablo yaratmak mmkndr ancak indekslemenin getirdii avantaj kaybederiz. Tablolarda veriler bizim giri sramza gre bulunurlar. stored

DB yaratlrken DB'nin toplamda kaplayaca alan belirtilerek tahsis edilir. 8 KB'lik page'ler oluturulur ve satrlar buralara yazlr. (Arama yaplrken PK'lerle indeksleme yaplmamsa arama page page yaplr. Buna Paging denir) DB ile ilgili tm nesneler CREATE komutu ile yaratlr: CREATE TABLE CREATE PROCEDURE CREATE FUNCTION Bu nesnelerde daha sonradan deiiklik yapmak istediimizde ise ALTER komutu kullanlr. ALTER TABLE ALTER PROCEDURE ALTER FUNCTION Bu nesneleri silmek istediimizde ise DROP TABLE DROP PROCEDURE DROP FUNCTION Bu komutlara Data Definition Language (DDL) denir

SQL komutlar trlerine gre gruplara ayrlr. Data'y tanmlayan komutlara DDL komutlar denir.

Tablo zellii deitirme: ALTER kullanmna bir rnek: ALTER TABLE Stok ADD CONSTRAINT pk_StokKod PRIMARY KEY(StokKod) Primary Key yaplan alandaki deerler unique olmaldr. LIKE kullanm: SELECT * FROM Stok WHERE StokKod LIKE 'RAM%' Query'de eit deildir demek iin <> ya da != kullanlabilir. StokKod'unu aadaki gibi parse edebiliriz. [Ama: StokKod EK ile balayp R ile devam etmeyenleri getir: SELECT * FROM Stok WHERE StokKod LIKE 'EK%' AND SUBSTRING(StokKod, 3, 1) != 'R'

Bir dng ile tablodaki rnlere fiyat atayalm: Stok tablosunda ka tane satr olduu yle bulunur: SELECT COUNT(*) FROM Stok Sentaks: COUNT(<kolon_ad>)

SQL Server'da tm deikenlerin bana @ iareti konulur. Deiken tanmlamas, bu deikene deer atanmas ve deikenin SELECT edilmesi aadaki gibi yaplr: DECLARE @SatirSayisi int SELECT @SatirSayisi = COUNT(*) FROM Stok SELECT @SatirSayisi

rnek bir SQL Query kodu - Dng ierir: DECLARE @SatirSayisi int, @Sayac int SELECT @SatirSayisi = COUNT(*) FROM Stok SELECT @SatirSayisi SET @Sayac = 1 -- Burada SELECT'te kullanlabilir ancak SET anlama daha uygundur WHILE (@Sayac <= @SatirSayisi) BEGIN UPDATE Stok SET SatisFiyat = @Sayac * 2 -- Hepsi ayn fiyatta olur SET @Sayac = @Sayac + 1 END

STORED PROCEDURES: Sklkla yaplan query ilemleri iin procedure yazlr ve kullanlr. Bir dier avantaj da normal query'lerden hzl almalardr nk stored procedure'ler derlenmi halde saklanr. Derlenmenin anlam bir, kod sentaks bakmndan geerlidir, iki, eer procedure' kaydettiysek o procedure iin bir alma plan DBMS tarafndan oluturulur. Mesela DBMS proedure' nasl daha hzl altrabilir, indeksleri internal olarak inceleyerek bir alma plan oluturmaktadr. Bu ilem de yalnz bir kez yaplr. Artk stored procedure derlendii iin bu iki durum asndan da hazrdr. Stored procedure'ler son olarak SQL Injection' da engeller. rnek Stored Procedure kodu: CREATE PROCEDURE up_FiyatDegistir @Degisiklik int -- Prosedre geilen parametredir, deiken deil AS UPDATE Stok SET SatisFiyat = SatisFiyat * ((@Degisiklik + 100) / 100)

ALTER PROCEDURE up_FiyatDegistir @Degisiklik decimal -- Ondalk ilemler yaplabilmesi iin decimal olarak alter ediliyor AS UPDATE Stok SET SatisFiyat = SatisFiyat * ((@Degisiklik + 100) / 100) EXEC up_FiyatDegistir 10 -- EXEC bir stored procedure' altrr

CREATE PROCEDURE up_RamFiyatDegistir @Degisiklik decimal(6, 2) AS UPDATE Stok SET SatisFiyat = SatisFiyat * (@Degisiklik + 100) / 100 WHERE UrunGrup = 'RAM' EXEC up_RamFiyatDegistir 10

CREATE PROCEDURE up_RamFiyatDegistir @Grup varchar @Degisiklik decimal(6, 2) AS UPDATE Stok SET SatisFiyat = SatisFiyat * (@Degisiklik + 100) / 100 WHERE UrunGrup = @Grup EXEC up_RamFiyatDegistir 'RAM', 10 -- Ya da, EXEC up_RamFiyatDegistir @Degisiklik = 10, @Grup = 'RAM'

12 Temmuz 2008 LSANSLAMA SQL Server'n yeteneklerine ve destekledikleri donanma gre bir ka edition' var. En basit ve cretsiz olan Express Edition, en nemli eksiklerinden biri ynetim aralar yok. DB max. 4 GB'ye kadar kabilir. RAM ise 1 GB'ye kadar kabilir. Bir sr versiyonu Workgroup Edition'dr. ki ilemciye kadar ve 4 GB'ye kadar donanm limiti var. Her bir client access'i 143 dolar. Sonra Standard Edition geliyor, 8 RAM, 4 ilemciye kadar destei var. En st seviyede Enterprise Edition var. [Data Center Edition ve Developer Edition'lar ticari edition'lardan farkl zellikler ieriyor. Data Center Edition'da MS tarafndan onaylanmam hi bir driver almyor. Bu sayede ok salam.] Tm edition'larn 64 bit ve itanium versiyonlar da bulunmakta. Client Access Lisans ayn anda ka kullancnn balanp kullanabileceini belirler. Bunun tesinde her biri iin yeni bir client access lisans alnr. Ayrca processor lisans da var. ok sayda client varsa processor lisans leklenebilirlii artrmak iin gerekebilir. ekirdek saysnn nemi yok, ift ve drt ekirdekler tek ilemci saylyor. Web iin lisanslama durumu farkldr. Ayrca bir web lisans alnyor. (nceden Web Connector lisans vard, artk bu lisans yok, snrsz device lisans almak gerekiyor.) Ksaca nemli olan processor ve client access lisanslardr. SQL Server'da ka ekirdek olduu nemli deil ancak Oracle ekirdee gre fiyat belirliyor.

SQL SERVER KURULUMU: .NET zerinde alan fonksiyonlar, prosedrler, trigger'lar yaratlabiliyor. Bazen kendimiz SQL'de fonksiyon yazarz ancak bunun yetersiz kald yerlerde .NET ktphanesi ile fonksiyon, stored procedure, trigger yazabiliyoruz. Ancak,

bunu ok kullanmamak gerek nk external .dll'ler'i SQL Server'a eklememiz gerekir. Hele .NET'te yazlan user defined veri trleri SQL Server'n performansn hissedilir ekilde drr. Developer Edition Enterprise Edition'n salad tm zellikleri salar ancak mteriye Developer Edition kuramayz, yasal deil. Analysis Services, Integration Services... nedir ? Bunlar, Business Intelligence zmnn parasdr. Bir bankann alan aktif DB'sini dnelim, ya da bir firmann cari-stok takip db'sini. Bu tr DB'lere OLTP (Online Transactional Processing) DB'ler denir. Biz derste bunlar greceiz. Veriler girildike st ve orta ynetime raporlanmas gerekir ancak raporlama iin OLTP DB'ler performans kayb olmasn diye kullanlmaz. Bunun yerine Integration Service kullanlarak DB'deki belirlenen veriler birtakm gerekli dzenleme ilemleri yapldktan sonra bir veri ambarna alnr (Veri ambar (Dataware House da denir, aslnda bildiimiz DB'den bir fark yok.): Gnlk, zerinde alan bir ya da bir ok kaynaktan gelen verileri tutan yer. Daha sonra bu veri ambarndan raporlar ekilir.) Veri ambarna neden gerek var ? nk data'lar birden ok server'dan farkl formatlarda geliyordur zaten, veri ambarnda ortak bir yapya kavuturulur, veri zerinde dzenlemeler yaplr, ayrca raporlama ilemlerini OLTP tr DB'ye yaptrrsak ekstradan performans kayb oluur. Verileri tm server'lardan bir veri ambarna Integration Services ile toplarz. DataWare house'a gnlk veriler dolar. Reporting Services iin IIS gerekir. Gnlk normal raporlarmz reporting services ile raporlarn yapsn oluturup web server'da publish ederiz ve kullanclar onlara yetki verdiimiz lde bu raporlara eriebilirler. Reporting Services ile statik raporlar alnr. (Excel tarz bir rapor mesela.) Yani raporun yaps statiktir ancak Analysis Services ile raporun yaps olap kp eklinde tasarlanr ve client'lar istedikleri krlmlardan srkle brak ile client'lar raporlar istedikleri gibi dzenleyip istedikleri kadar derine inebilirler. Client'lar ksaca rapor zerinde filtreleme yapma yeteneini kullanabilirler. Bu yetenee sahip raporlara dinamik raporlama denir. Notification Service uyar servisidir, mesela DB'ye u tabloya data eklendiinde beni uyar diyebiliriz.

Database Service'te Full-Text Search ve Replication bulunur. Replication, rnein DataWare House olutururken istediimiz verileri birden ok kaynaktan toplayabiliyorduk, replication da buna benzer ancak temel fark ve kullanm ekli yledir: rnein, stanbul ve Ankara'da iki server'mz var. stanbul'da SQL Server bulunuyor, Ankara'da 10 client stanbul'a sorgulama yapyor. Bu 10 kii stanbul'daki server'dan ayn verileri sorguluyorsa (ehirler aras balantlar yavatr) buna are olarak Ankara'ya da bir server kurulur ve Ankara'da client, data istediinde o veri stanbul'dan bir kere gelir, geldi mi Ankara'daki server'a kaydedilir, bir daha ayn data talep edildiinde artk talep stanbul'daki server'a gitmez, bu data Ankara'daki server'dan alnr. Yani, zetle veri client'a yaklatrlm olur. Yani replication, bir, farkl blgelerde olan veriyi merkezde birletirmek iin kullanlabilir, iki, her client kendi local'indeki ilemleri dier yerlerdeki server'lara ulatrr, data client'a yaklatrlr. Ksaca ve zetle, replikasyon verinin bir kopyasnn kartp datarak data'y kullancya yaknlatrmaktr.
Full-Text Search nedir ?

SELECT * FROM Stok WHERE StokKod LIKE 'RAM%' Burada, LIKE kullanm ile RAM ile balayan tm string'lere bakabiliriz. Aklama satrnn Varchar(500) olduunu dnelim. Varchar'lar 5000 karaktere kadar kyordu nceden artk 8000 karakterden 2 GB'ye kadar destek veriyor. Bu denli byk bir alanda yukardaki gibi LIKE kullanlan bir sorgu yaptmz dnelim. Aranan sonucu data ok byk olduu iin bulabilmesi ok g ve uzun olacaktr. Ya da bir dier rnekle, rnn kullanm kitapn db'de tutuyoruz. Peki aranan kolayca nasl bulacaz ? Bir kolonda tutulan her bir szck nceden SQL Server tarafndan indekslenmi olsa idi arama ok daha ksa srede bulunurdu. Yani, byk karakter alanlarnda aranan sonucun daha hzl bulunabilmesi indeskleme yaplr ve indesklerle aranmas iin FullText Search component'i kullanlr.

Client-Component'lerde neler bulunur ?


1) Connectivity Component: Asl DB ilemlerini yapan SQL Server Component'tir. Server'lardan isteklerde bulunan birtakm component'ler gerekir. Server'a balanmamz salayan component'e connectivity component denir. (client server'a nasl balanacak, veriyi nasl isteyecek ?) ODBC, Native SQL Client, OleDb birer Connectivity Component'tir ve birtakm API'ler ierirler. API'ler ile programc bir arayz zerinden DB ile konuur. OleDb standart bir API'dir ve OleDb'yi destekleyen kaynaklara OleDb ile eriebiliriz. rnein Access, Oracle kaynaklar gibi. (Native SQL Client ile hzl bir ekilde SQL Server'a eriilebilir.) ODBC ok nemli bir component nk ODBC'yi desteklemeyen kaynak yok gibi. ODBC C dili ile yazlmtr. ODBC bizim komutlarmz DBMS'lerin anlayaca ekle, DBMS'nin cevaplarn bizim anlayacamz ekle evirir. ODBC ne ie yarar ? rnein, Excel'den SQL'e, Oracle'a ya da Access'e erieceiz, normalde bu ne de erimek iin gerekli component'i yazarak ODBC'nin iine biz koyabilirdik. Peki ya ilaveten Word'den ya da MySql'den erimek istersek ? Programcy bu skntdan kurtarmak iin ODBC kendi ierisinde bunlar yapmakta ve bize bir interface ile eriim vermektedir. Eer, native olarak erime imkanmz yoksa hepsine ODBC ile eriebiliriz. Client tarafnda kod yazan firmalar ODBC ile konuacak ekilde yazarlar ve DBMS programclar da ODBC iin driver yazarlar. rnein, Progress ile Word' konuturmak istiyorsak, Progress'in web sitesinden gerekli ODBC driver' indirilir ve gerekli ilemler gerekletirilebilir. [ODBC (Open Database Connectivity)nemli. Hemen hemen tm sistemlere ODBC destei bulunur.] Connectivity Component, Microsoft Data Access Component (MDAC) olarak bilinir.

SQL Server'a balanacak tm client'lara Client Components kurmak gerekir. Ancak zaten ou client component Windows ile birlikte otomatik kurulur. 2) Management Tools: SQL Server Management Studio bir management tool'dur. Yani, SQL Server' ynetmek iin gereken aralardr. Management Tools nereye kurulur ? SQL Admin ya da yazlmclar Management Tools'u souk server odasndaki server'a deil de kendi bilgisayarlarna kurarlar. 3) Business Intelligence Development Studio: Business Intelligence Development Studio ile entegrasyon, raporlama, analiz servis ilemleri yaplr. Visual Studio arayz ile alr. Template'ler ierir. Buna ksaca BIDS denir.

4) Legacy Component: Eski SQL 2000 Server nesnelerine erimek iin kullanlabilir. SQL Server Books Online SQL Server dkmantasyonudur. [SQL 2005 Training Kit kitabn kullanacaz.] SQL Server 2005 ile birlikte client'tan gelen taleplere Web Service olarak cevap verebilme yetenei gelmitir. Web Service DB'den ald bilgiyi client'a deil programcya dndrr. Bunu web service'i programlayan kiinin yazd interface aracl ile (rnein, web servisteki fonksiyonu arp geri dn deerinden faydalanarak) yapar. Partitioning, ok byk tablolalarmz varsa (milyon satrlk) ve ok youn ilemler yapyorsak bu durumda makinamza birden fazla disk takp her birinde birer dosya oluturup DB'yi farkl dosyalar zerinde tutabiliriz. Bylece okuma (arama) yapmak gerektiinde o bilginin partition edildii diskte daha az saydaki kaydn iinde arama yapacaktr. Bu sayede performans kazanc salanr. DB'lerde kilitleme (database mirroring) thread senkronizasyonu iin yaplr.

FAULT TOLERANCE Clustering: Normalde veriler bir makinada bir disk zerinde durur. Bu disk bozulursa veriler gider. Bunun iin bir makinada birden fazla disk kullanlr, birine yazlan veri dierine de yazlr, bir disk bozulursa iler hem dier disk zerinden devam eder, i durmaz, hem de bir veri kayb gereklemez. (RAID1 / Disk Mirroring) (RAID0 ise rnein bizim 5 TB'lik bir diske ihtiyacmz var. Piyasada ise 1 TB'Lik diskler var. Gidip 5 tane 1TB alp bunu tek bir 5TB diskmi gibi gsterebiliyoruz. Buna RAID0 ya da Disk Stripping denir. RAID 5'te ise 6 diskten 5 TB elde ediyoruz. (Strip disk with parity denir) DB sistemlerinde genelde nce diskler RAID1 yaplr. (40 disk ile disk mirroring yaplarak 20 TB elde edilir.)Ardndan da RAID0 yaplr. (20 TB'lik tek bir volume elde edilir.) Buna RAID 1 + RAID0 ya da RAID10 denir. Bir, veri kayb olmamal, iki, i durmamal, RAID sistemleri bunu salar. Peki, makinann anakart bozulursa, bunun iin iki tane ayr makina kullanlr.

SQL SERVER KURUMUNA DEVAM Bir makinaya birden fazla SQL Server kurulabiliyor. Her birine bir instance denir. lk kurulan SQL Server'da default instance kk seilirse SQL Server'n ad da makinann ad olur. simlendirilmi bir kopya da Named Instance opsiyonu seilerek kurulur. Birden fazla SQL Server bulunan makinada balanmak istediimiz SQL Server'a bu isim ile eriiriz. Bu instance'lar farkl iki makinaya iki tane SQL Server kurulmu gibi davranr. Birden fazla instance'a neden ihtiya olur? retim ortamnda asla yaplmaz. Ama, renim amal olarak mesela replikasyon yapacaksak kurulabilir. Service Account: SQL Server client-server bir yazlm olmak zere server ksm bir ka paradan oluur: SQL Server(Motor) / SQL Server Agent(SQL Server'da zamanlanm ileri yerine getiren component) / SQL Browser(SQL Server'a baka makinalardan eriilmesi iin SQL Server' aa tantan component) Bu component'lerin her biri ayr birer dosya ve windows servis olarak alr. Hepsi birer windows servis olarak yazlmtr. Bu

yzden balang tr servisin iletim sistemi aldnda otomatik mi ya da manuel mi olarak balayacan belirlemekte kullanlr. Bir servisi balattmzda o servis o anda log-on olmu kiinin yetkisi ile alr. Sa tklayp farkl altr diyerek baka bir kullancnn yetkisi ile de altrlabilir. SQL Server altrldnda baka bir makinann kaynana eriecekse oraya bir kullanc ad ve ifre ile erimesi gerekir. Bu tr a zerindeki dier makinalara erimek gerektiinde Use a domain user account ksmnda bu kullanc bilgileri girilmelidir. Her bir servis iin de farkl kullanc ad ve ifresi verilebilir. SQL Server.exe alrken adaki bir kaynaa erieceinde domain kullanc ad ve ifresini alarak o kullanc yetkisi ile alr. [Burada, bahsedilen client'lara verilen hizmet hakknda deil. Server'n kendisinin birtakm ilemler iin adaki baka bir makinaya erimesi ile ilgilidir.] Sadece kendi makinasnda kullanlacaksa SQLServer.exe Use the built-in system account: Local system yaplr. Authentication Mode: Kullanclar adaki bir makinada tanml, bu makinaya Domain Controller denir ve kaytlarn tutulduu yere Active Directory denir. Bu yapya Domain yaps denir. SQL Server'da da birtakm tablolarmz olacak. Biz bu tablolarla ilgili olarak kullanclara birtakm yetkiler vereceiz. Bunun iin kullanclarn kullanc ad ve ifre bilgileri gerekli. Bunu salamak iin yeni kullanc ad, ifre tanmlamak yerine kendi Windows Domain isimleri kullanlacaksa Windows Authentication Mode seilir. Network'e balanan bir bayi varsa ve bu bayi bizim domain'imizde tanml deilse mixed mode seilir ve bu kullanc SQL Server iinde tanmlanr. Biz kurulumda mixed mode'u seeriz, bu modda SQL server'n kendi ierisinde tanml olan "sa" isimli kullanc devreye girer ve bu kullancnn SQL Server'da hereyi yapmaya yetkisi vardr. Eer, Windows Authentication Mode'u seseydik "sa" kullancs aktif olmazd. Makinadaki administrator grubu yeleri makinalarda her eyi yapmaya yetkilidir. Yani, SQL Server'n admin'i olurlar. Mixed Mode seili ise "sa" da tam yetkilidir. Bir ada ise Domain/Administrator grubu vardr ve SQL Server'da her eyi yapmaya yetkilidir. Collation Settings: SQL Server tablolarda verileri tutar ve biz birtakm sorgularla verileri birbirleri ile karlatrrz ya da sralarz. Bu karlatrma neye gre yaplmaktadr ? [string karlatrmas ve sralamas] Collation'da, verilerin birbirleri ile karlatrrken ve sralarken hangi kurallara uyacak ve hangi dile gre yapacak, bu belirlenir. Burada seilen ayar default collation olur. SQL Server'da ayrca, tablodaki kolonlarn her birinin collation' ayarlanabilir. Binary sralama: ASCII tablosundaki sralama kullanlr. ('a' != 'A' && Z > a) Accent - sensitive: if ( == a) ; gibi. Aksan iaretlerini dikkate alr. Biz burada default ayarda brakabiliriz. SQL Collations Opsiyonu: Eski SQL Server versiyonlarna Collation uyumu salamak iin kullanlr. SQL Server SERVSLER Administrator Tools > Services listesinden SQL Server servisi bulunabilir. ift tklayarak SQL Server servis ad grlebilir. SQL Server'daki DB'ler dorudan Active Directory zerinden yaynlanabilir.

SQL Server VSS (Visual Source Safe) Writer: SQL Server'daki grup almalarnda source safe kontrol yapar. SQL Server isimlendirilmi bir instance ise hizmet adnda $ iareti bulunur. Management Studio'da log-on'da "makina\instance_ad" yazlr. BERK\MSSQL$SQLEXPRESS gibi. SQL Server ile adaki bir makinaya balanamyorsak SQL Server Config'den Surface Area Configuration'a baklmaldr. Sadece Locale deil Locale & Remote seili olmaldr. SQL Server 1433 no'lu port'u kullanr. A zerinde firewall'dan kaynaklanan bir problemde hizmeti veren bilgisayar bu port'u amaldr. Stok Tablosu > Script Database As > Create To > Tabloda CTRL + 0 o hcreyi null yapar. Bir tabloyu tamak iin Explorer'dan DBsmine tkla > Tasks > Detach, user'lar drop etmek gerekli. Ardndan windows explorer'dan .mdf ve .ldf dosyalar rnein flash'a copy ederek tayabilirim. Databases > Attach diyerek geri ykleyebilirim.

13 Temmuz 2008 Client makinaya ayrca bir yazlm kurulmaz. Zaten MDAC iletim sistemi ile birlikte kurulu gelir. Admin makinalara management studio kurulur, souk odadaki server'lara da SQL Server kurulur. Bir kolon primary key yaplnca oraya bir clustered index atanr. Clustered index ile tablo ASC olarak sralanr. Bir rnn miktarna gre index yapacaksak: CONSTRAINT pk_StokMiktar PRIMARY KEY CLUSTERED ( [StokMiktar] DSC ) Object Explorer'da DBName zerinde sa tkla > Tasks > Generate Scripts diyerek bir tablonun tm script'ini kartabiliriz.

NORMALZASYON KURALLARI - Birinci Kural ve Alt kurallar Database'imizin normal kurallar ierisinde tasarlanmasna normalizasyon denir. Normalizasyon kurallar biraz aada aklanmtr. Bir tablonun bir kolonuna girilecek veriler sadece bir baka tablodaki deerlerden biri olacaksa burada foreign key ilikisi kurulur. Bu aslnda bir constraint (kst) ilikisidir. Foreign key ilikisi kurarken kolon adlarnn ayn olmas zorunlu deildir. Ama byle olmas tercih edilir.

Foreign Key SQL'de yle tanmlanr: CONSTRAINT FK_BolgeNo FOREIGN KEY(BolgeNo) REFERENCES Bolge(BolgeNo)

Referans edilen yer primary key (parent) tablosudur, referans eden ise foreign key'dir. External Disk hem External rn grubundadr hem de disk grubundadr, peki hangi gruba ekleyeceiz, ya da all-in-one rnleri ne yapacaz, hem fax, hem fotokopi, hem yazc, hem de scanner, hepsine birden eklersek bilgi tekrar olur, peki ne yapacaz ? Stok tablosundaki UrunGrup kolonu bu durumda faydal bir kolon deil. Bunu stok tablomuzdan kaldrmamz gerekiyor. Entity-Relationship Diagram'lar (E-R Diagram) Entity, DB'de varlk anlamna gelir. DB'lerde varlklar tablolarla temsil edilir. Tablolar arasndaki izgilere ise relation denir. Ciddi bir db tasarlanrken tasarm nce baka bir arala (Rational Rose gibi) yaplr, tasarm grsel olarak oluturulur ve bu programa u DB Server'da git ve bu db'yi olutur denir. Programn kendisi gerekli SQL ilemlerini gerekletirerek SQL Server'da DB'yi oluturur. Erwin, Visio, Rational Rose grsel DB tasarmnda kullanlan balca akla gelen aralardr. Entity-Relationship Diagram'lardaki relation izgilerinde eitli iliki ekilleri vardr. 1) Bire ok (One to Many): Primary Key'deki kolon birdir, fakat foreign key'deki many'dir. (One taraf primary key tablosudur, Many taraf foreign key tablosudur.) 2) oka ok (Many to Many): rnein, Birden ok stok birden ok rn grubuna sahip. 3) Bire bir (One to One): Bir tablonun primary key'i dier bir tablonun primary key'ine bal ise bu iliki tr one to one'dr. (Bire bir ilikilerin ou tek bir tabloda da yaplabilir.) liki kurarken ilikinin bir taraf primary key olmaldr. Bu tercih edilendir ancak kesin art deildir. Alternatif olarak iliki kurulan tablodaki kolon unique'se de olabilir. liki biimi ilikide primary key'lerin nasl kullanld, kullanlp kullanlmad ile alakaldr.

19 Temmuz 2008 Database Entity-Relation Diagram: Tablolar ve tablolar arasndaki ilikileri gsteren diyagrama denir. Ksaltmas E-R Diagram'dr.

Stok
StokKod

Sehir
SehirKod SehirAd BolgeNo

Bolge
BolgeNo BolgeAd

StokUrunGrup
StokKod UrunGrup

Stokad Acklama Stokfiyat Kdv Miktar

Musteri UrunGrup
UrunGrupKod UrunGrupAd
MusteriNo MusteriAd Adres SehirKod Bolge VergiDairesi VergiNo Bakiye

Veritabannn doru bir ekilde tasarlanmas iin uygulanmas gereken kurallardr. Normalizasyon ilemi ise db'nin doru tasarlanmas iin db'nin normalizasyon kurallarna gre ekillendirilmesine denir. Normalizasyonun kural vardr: 1) Bir ka alt kuraldan oluur: a) Her bir tabloda her bir satrda sadece o satr temsil edecek bir primary key olmal. b) Field'lerdeki veriler atomik olmaldr. Yani, her bir field sadece tek bir veri iermeli. Mesela Stok tablosunda stok gruplar olsa ve bir rn birden fazla grupta olsa rnn hangi gruba ait olduunu belirten kolona birden fazla veri girmek gerekirdi. Bu olmamaldr. Bir tane veri olmaldr. c) Tablolarda veri tekrar olmamal. 2) Tablolardaki tm kolonlar PK'ya bal olmal, baka bir field'e deil. 3) Composite key olan tablolarda PK dndaki tm alanlar Composite Key'in tamamna bal olmal, sadece bir ksmna deil. Bu birinci kurala uygun tablolara birinci normal formdadr denir, veri tekrarndan kanlm, tm veriler bir primary key'e bal ve tm satr o primary key temsil ediyor ve tablo atomik yapda demektir. Teorikte yle istense de bir istisna olabilir ve her tabloda PK olmak zorunda deildir. Mteri tablosuna SehirAdi konsayd: 1 2 3 FirmaA FirmaB FirmaC 34 34 35 Istanbul Istanbul zmir

Bu tablo yukardaki ikinci kurala uymuyor. Bir stanbul verisi tekrar ediyor. Ayrca kullanc birine stanbul yerine Ist yazm da olabilir. Bu durumda biz stanbul'daki mterilere bakmaz istesek WHERE clause'a doru veri geemeyeceiz. ki, tablodaki Istanbul ve zmir bilgileri primary key'e deil ehir koduna bal. Bu durumlarda, ilgili bilgi baka bir tabloya normalizasyon yaplarak alnarak sonra bu tablolar arasnda iliki kurulmaldr. ehir tablosu alr ve SehirNo ile SehirAd ierir. Musteri tablosundaki SehirKod'dan Sehir tablosundaki Sehirkod'a foreign key ilikisi kurulur. Sehir one, msteri many'dir. Ayrca ve nemli olarak child tabloda olmayan hi bir bilgi

msteri tablosunda seilemeyecektir. Yani bir foreign key kst koymu olduk. Hatal bilgi girilmesini de engellemi oldu. Sehir tablosuna BolgeAd koysak bu veri gene tekrarlayan veri olacaktr. Bu sebeple bir bolge tablosu atk ve Sehir tablosuna bir BolgeNo koyduk. Sehir tablosundaki BolgeNo ile Bolge tablosundaki BolgeNo arasnda bire ok iliki kurduk. Stok tablosunda UrunGrup olsa ne olurdu ? Girilen rnler tek bir rn grubuna aitse bir sorun olmayacakt. Ancak all-in-one tr bir rn geldiinde bir rn birden fazla rn grubuna ait olduunda bu durum 1. kuraln 2. maddesini ihlal eder. Atomik deildir. Bir kolonda birden fazla veri tutulmu olur. Burada, Urun gruplarna gre listeleme yapsak nasl yapacaz ? Hata oluur. Ancak LIKE ile bakabiliriz. Fakat bu kez de alakasz baz veriler dnebilir. Verilerin atomik olmamasnn zarar verileri gncellemek istediimizde sorun yaratmaldr. nk WHERE clause'una geilecek data sorunludur. Bunun gibi durumlarda bir tane UrunGrup tablosu yaratrz. UrunGrupKod ve urunGrupAd stunlarn ierir. Stok tablosundan UrunGrup stunu kaldrlr. StokKod'u UrunGrup'a koysak: RAM RAM Memory Memory RAM128 RAM256

Hata ! Primary key unique deil ! yle yapsak: RAM RAM Ram128 RAM256 Memory Memory

lk iki kolon primary key olabilir ve unique'lik salanabilir. Birden fazla kolonun primary key yaplmasna composite key denir. Ancak bu tasarmda gene veri tekrar yaanyor. UrunGrupKod'u tekrar etmekte. Ayrca Memory verisi Ram128 verisine deil RAM'e bal yani composite key'lerde satrdaki dier alanlar composite key'in tamamna bal olmaldr. Bir ksmna deil. Bu kural normalizasyonun nc kuraldr. Yani bu tasarm hataldr nk normalizasyonun nc kuraln ihlal etmektedir. Ayrca birinci kuraln nc maddesini de ihlal etmektedir: Veri tekrar vardr. Stok tablosu ve UrunGrup tablosunda tutulamayan UrunGrup alan yeni bir tablo yaratlarak bu tabloda tutulur. Tablo ad StokUrunGrup'tur ve StokKod ile UrunGrup alanlarn ierir ve UrunGrup tablosu ile StokUrunGrup tablosu arasndaki UrunGrupKod alanlar arasnda bir foreign key ilikisi olur. StokUrunGrup tablosu aadaki gibidir: RAM128 RAM256 DSK80 DSK120 HP1480 HP1480 HP1480 RAM RAM DSK DSK PRN FAX SCN

StokUrunGrup tablosunda bir primary key yok. Burada yaplmas gereken StokUrunGrup tablosundaki iki kolonun da composite key olarak primary key yaplmasdr.

ki tablo arasnda oka ok iliki kurmak iin kullanlan ara tablolara Junction Table denir. NORMALZASYON KURALLARI - nc kural PK composite key olan bir tabloda tm alanlar PK'nn tamamna bal olmaldr. Sadece birine deil. liki ekillerinde primary key'in olduu tablo one, foreign key'in olduu tablo many tarafdr. rnein, ehir bir tanedir ama o ehirden birden ok mteri olabilir. ehir - mteri ilikisi bire ok ilikidir. oka ok iliki nasldr ? Normalde DB'deki verilerin ou bire oktur. oka ok ilikiye UrunGrup ve Stok tablolar verilebilir. Aradaki Junction Table olan StokUrunGrup dier iki tablo ile bire ok iliki kurmutur. Bir rn birden fazla grupta olabilir ve ayrca bir grupta birden ok rn olabilir. oka ok ilikilerde arada mutlaka bir tane junction table (birletirme tablosu) bulunur. rngrubuna gre indirimler yapmak istesek bunu nereye koymalyz ? UrunGrup tablosuna UrunIndirimOran olarak konabilir. Ancak, ileride bir sr eitte farkl indirim olursa bir indirim tablosu yaratmak daha mantkl olacaktr. Bire bir iliki: ki tane tablodaki PK'lar birbirine balanr. Bire bir ilikiler yerine veri aslnda tek bir tabloda da tutulabilir. rnein: Personel ve PersonelAccount tablolarmz var. Personel ve PersonelAccount tablolarnda SicilNo primary key'dir ve bu primary key zerinden iliki kurulur. Personel SicilNo Ad TCNo Adres PersonelAccount SicilNo Maa Neden iki tablo yaptk, tek tablo olsa tablo ok geni olabilir. Ayrca yetkilendirme asndan personel tablosunu baz kullanclar PersonelAccount tablosunu daha yksek yetkililer grmek isteyebilir. Tablolarda her bir satrdaki veri dier tablodaki bir satr bilgiye karlk gelir. te buna bire bir iliki denir. Ad soyad ayr ayr m yoksa tek bir kolonda tutulmal m ? Ancak ad ve soyad ile ayr ayr baz ilemler yaplacaksa ayr tutulur. Mesela telefon rehberinde soyadna gre arama yapmamz gerekir. Bu durumda ad soyad ayr ayr tutulur. Byle bir eyin gerekmedii durumlarda birleik tutulmas daha faydaldr. nk programatik olarak kiinin ad gerektiinde ad ve soyad alanlarndaki data'lar her defasnda birletirmek gerekir. Kendisi ile ilikili tablolara Self Join denir. liki kurarken kolonlar arasnda veri trleri ve uzunluklar ayn olmak zorundadr.

DB iki dosyadan oluur, tablolardaki data'lardan trigger ve procedure'lere kadar hepsi .mdf dosyasnn ierisindedir. Dier dosya ise .ldf dosyasdr. Bu dosya ise log dosyasdr. Bu dosyalar tanabilirdir. Bunlar, iletim sistemi C:'de ise .mdf dosyas D:'ye, log dosyas E:'ye konulur. sp_attach_single_file_db dbName, path => db'yi Sql eder, .mdf dosyas gsterilir. Kendisi bo bir log dosyas yaratr. Server'a attach

Object Explorer'dan db'ye sa tkla > tasks > generate scripts... > Foreign Key'in grsel olarak eklemek iin object explorer db > tables'tan ilgili tabloda artya basp keys > new foreign key > tables and columns specisification seilir. Fatura tablosu oluturulurken iki tablo ile temsil edilir. Fatura tablosu ve FaturaDetay tablosu. Faturada bir kere olanlar Fatura'ya rnler gibi veriler FaturaDetay tablosuna yazlr. ALTER TABLE Fatura ADD GenelToplam AS Toplam + Kdv => Hesaplama yolu ile alan bu ekilde oluturulabilir. Bu tr kolonlara computed columns denir.

19 Temmuz script'leri:
CREATE TABLE Personel ( SicilNo PersonelAd Adres Sehir Bolum BagliOlduguKisi ) CREATE TABLE PersonelUcret ( SicilNo AylikMaas kramiyeTutar kramiyeAdeti )

char(6) varchar(50) varchar(200) int int char(6)

NOT NULL NOT NULL, NULL, NOT NULL, NOT NULL, NOT NULL

PRIMARY KEY,

char(6) NOT NULL decimal(8,2) NOT NULL, decimal(8,2) NOT NULL, int NOT NULL

PRIMARY KEY,

-- nce Personel tablosuna veri girilmelidir. nce PersonelUcret tablosuna veri girii kstlanmtr. ALTER TABLE PersonelAccount ADD CONSTRAINT FK_SicilNo FOREIGN KEY(SicilNo) REFERENCES Personel(SicilNo) INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO Personel Personel Personel Personel Personel VALUES('1', VALUES('2', VALUES('3', VALUES('4', VALUES('5', 'Berk Acunas', null, 34, 1, null) 'Taran Acunas', null, 34, 1, null) 'Kaan Aslan', null, 34, 2, '2') 'Cem Karaca', null, 35, 2, '3') 'Ali Veli', null, 35, 2, '3') 5000, 4000, 2500, 1300, 1200, 5000, 4000, 2500, 1300, 1200, 0) 0) 4) 2) 2)

PersonelUcret PersonelUcret PersonelUcret PersonelUcret PersonelUcret

VALUES('1', VALUES('2', VALUES('3', VALUES('4', VALUES('5',

CREATE TABLE Fatura ( FaturaNo IDENTITY(1,1), BelgeNo IrsaliyeNo MusteriNo

int char(10) char(10) int NULL, NULL,

NOT NULL

NOT NULL,

Tarih Toplam Kdv ) CREATE TABLE FaturaDetay ( FaturaDetayNo IDENTITY(1,1), FaturaNo StokKod BirimFiyat Adet

datetime NOT NULL, decimal(10,2) NOT NULL, decimal(10,2) NOT NULL,

CONSTRAINT PK_FaturaNo PRIMARY KEY(FaturaNo)

int int char(10) decimal(8,2) int

NOT NULL NOT NULL, NOT NULL, NOT NULL, NOT NULL,

Tutar AS BirimFiyat * Adet, CONSTRAINT PK_FaturaDetayNo PRIMARY KEY(FaturaDetayNo), CONSTRAINT FK_FaturaNo FOREIGN KEY(FaturaNo) REFERENCES Fatura(FaturaNo), CONSTRAINT FK_StokKodFatura FOREIGN KEY(StokKod) REFERENCES Stok(StokKod) )

20 Temmuz 2008 Bir constraint T-SQL ile aadaki gibi kaldrlabilir: ALTER TABLE Fatura DROP CONSTRAINT PK_FaturaNo Mevcut veriler arasnda uygun bir PRIMARY KEY aday yoksa bir IDENTITY(1,1) tanmlanmaldr. Db owner'n deitirmek iin aadaki script kullanlr: SP_ChangeDbOwner 'sa' Bo bir DB'ye sa tklayp import data > next > data source se > destination' se > default: copy data, dier k query ile dnen set'i import eder > Table ve View'ler seilir > Execute Immediately | Save SSIS Package > ... INSERT yaparken ekleyebiliriz: bir SELECT'in sonucunu veri trleri uyuyorsa kullanp

INSERT Bolge(BolgeNo, BolgeAd) SELECT Miktar, StokAd FROM Stok Burada, Stok'tan dnen miktar verileri Bolge tablosundaki BolgeNo'ya, StokAd verileri BolgeAd kolonuna insert edilir. Composite Key script ile nasl konulur: ALTER TABLE StokUrunGrup ADD CONSTRAINT PK_StokKod_UrunGrup PRIMARY KEY(StokKod, UrunGrup) MSSQL'in script dili T-SQL'dir. Oracle'daki PL-SQL'dir. SQL komutlar e ayrlr: 1) Data Definition Language (DDL): CREATE, ALTER, DROP. 2) Data Manipulation Language (DML): Update, Insert, Select, Delete, Join vb...

26 Temmuz 2008 SYSTEM DATABASES Biz bir DB yarattmzda SQL Server gidip System Databases'daki Model Database'i template olarak alarak bizim db'mizi ekillendirir. Model database'in ilevi eer biz zelliklerini vermemisek default olarak oradan modeli alr. Oluturmak istediimiz tm DB'lerde rnein kullanacamz bir stored procedure etc... varsa ve bunu model db'ye koyarsak bundan sonra oluturduumuz her DB'ye bunlar ekler. Master Database'i: SQL Server'da bir ok nesne tutulmaktadr: DB'ler, login'ler, security nesneleri gibi, Sql Server'm kendisine ilikin kendi almas iin gerekli verilerin tutulduu database master database'dir. Mesela bu server'da hangi db'ler var, db'ler isim ve dier zellikleri bunlar SQL Server tarafndan bilinmeli, bu veriler Master Database'de saklanr. SELECT * FROM sys.sysdatabases => Server'daki tm db'leri getirir. sys emasndaki sysdatabases sistem view'idir. ema gruplandrma amac ile kullanlr. emay namespace gibi dnebiliriz. Sat emas, mteri emas gibi. ema bir container ve iinde baka DB'leri tutar. Ya da her kullanc iin bir ema yaplr ve her kullanc kendi db'lerini kendi emas altnda tutabilir. Oracle'da bir server'n bir db'si olabilir. Bu bir ksttr. Bunun iin Oracle ema mantn oluturmutur. MS, Oracle ile yartndan ema mantn MSSql'e uyarlamtr. MSSql 2000'de ema yoktu, Kullanc mant vard. Master DB bir ekilde bozulursa riskine kar back-up'nn alnmas gerekli olabilir. En kt ihtimal ile DB usa veri dosyalar silinmeyecei iin hepsi yeniden oluturulabilir. msdb database'i: Zamanlanm grevlerin (job) tutulduu db'dir. altka tutulan history'ler ve bunlarla ilikili eylerin sakland db'dir. tempdb database'i temp data'larn tutulduu db'dir. Bir db'yi oluturan script:

CREATE DATABASE [hb] ON PRIMARY ( NAME = N'hb', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.2\MSSQL\Data\hb.mdf' , SIZE = 3264KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'hb_log',

) GO

FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL.2\MSSQL\Data\hb_log.LDF' , SIZE = 1856KB , MAXSIZE = 2048GB , FILEGROWTH = 10%

Buradaki script, DB'nin zerine sa tklayp properties diyerek baktmz dzenlediimiz zelliklerdir.

ve

.ldf dosyas veritabannn tutarl kalmasn salayan bir dosyadr. rnein, biz bir tabloya veri eklediimizde bu veri .mdf dosyasna yazlmadan nce .ldf'ye yazlr, daha sonra .mdf'ye yazlr. Sonra da yazld diye .ldf'ye iaret koyar. Bu neye yarar ? Bir problem olutuunda, .mdf kaytlar yazan transaction bitmeden elektrik kesilirse, SQL Server yeniden aldnda .mdf'deki eksii, hatay tespit eder ve .ldf dosyasndan tazeler. Veri .ldf'ye yazlrken elektrik giderse asl DB'miz zaten .mdf olduundan durumdan bir zarar grmemi olacak. Bunun dnda biz bazen bir ilemi transaction olarak balatrz, mesela bir tablodan veri alp dier tabloya yazacaz. Burada transaction kullanlacak ve bir hata olduunda rollback yapar. kisi de olunca ilem geerlidir. te, bu transaction'da .ldf dosyas zerinden gerekletirilir. Ksaca .ldf dosyalar bir hata durumunda hatadan dnn salanmasnn gerektiinde kullanlrlar.

.ndf dosyas: eitli nedenlerle birden fazla db dosyas oluturmak istersek (db'yi partial tutmak iin) ilk yaratlan db dosyas .mdf dosyas olmak zere sonradan oluturulan db dosyalar .ndf uzantsna sahip olur. Nerelerde kullanlr? Birden fazla diskte birden fazla dosya oluturulur, yer ve performans kazanc salar. ok byk bir db olmadka .ndf dosyalar ok da gerekli deildir.

NAME = N'hb_log', FILENAME = N'C:\Program Files\Microsoft SQL Buradaki N'ler yannda yer alan karakterlerin Unicode olarak deerlerndirildiini gsterir. rnein DB 3MB olarak oluturulmu. 3MB dolduunda ne olacak ? SIZE = 3264KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ncelikle bir db olutururken db'yi 3 MB oluturmamak gerekir. nce bir tasarm yaplr ve db'nin boyutu tutaca data'ya gre belirlenir. Yukarda yaratlan db default olarak size'n model database'den almtr. DB dolduunda autogrow zellii aksa db bytlr ve ne kadar bytlecei FILEGROWTH = 1024KB ile belirlenir. Log dosyas .mdf dosyasnn %25'i kadar olur. Database > Properties > Files > ListView'deki AutoGrow kolonunun sana tklayarak deerleri ayarlanabilir.

ALTER DATABASE ADD FILE diyerek db'ye yeni bir dosya ekleyebiliriz. DB'ye yeni dosyalar eklediimizde verileri hangi dosyalara yazacana SQL Server kendisi karar veriyor. Ancak bu dosyalardan biri bozulduunda tm db'yi kaybederiz. FileGroup default olarak PRIMARY'dir. Eer birden fazla dosyamz varsa bunlar grupladmz yer FileGroup'lardr. FileGroup'u neye yarar? Senaryo: Youn alan 4 tablo var: Stok, fatura, mteri ve satc. Dier tablolar ok sk kullanlmyor. Bu durumda 5 dosya oluturulur, her bir youn alan tabloyu bu dosyalara koyarz. Ancak bir dosyay olutururken dorudan u file'n iinde olsun diyemeyiz ancak filegroup'a koy deriz. O zaman her bir tablo iin bir filegroup'u olutururuz. (Zor bir senaryo) Yedek alrken de sadece belirtilen tablonun yedeini al denebilir. Bir filegroup default olarak belirtilebilir.

FileGroup yaratan script: USE [master] GO ALTER DATABASE [hb] ADD FILEGROUP [FG2] GO

Database Properties > Options'da Collation' deitirirsek bu deiiklikten nceki tablolar etkilenmez. Deiiklikten sonraki tablolar etkilenir: USE [master] GO ALTER DATABASE [hb] COLLATE Turkish_CS_AI GO

Gerek bir database'de Recovery Model'i Full yapmak gerekir. Test amali db'lerde Single seilebilir. Bir dosya ok itiyse nasl kltlebilir ? DBCC SHRINKFILE (fileName, newSize) dosyann size'dr. // Capacity'yi shrink eder, alt-limiti

Bir database nasl shrink edilir ? DBCC SHRINKDATABASE (dbName, yzdekacboskalsin)

Peki, bir log dosyas size'ndan daha kk hale nasl getirebiliriz ? (.mdf'e yazlm ksmlar siler, gerisini backup eder, sonra da db'yi shrink eder): BACKUP log hb WITH TRUNCATE_ONLY -- Transaction log dosyasndaki .mdf -- dosyasna yazlm kaytlar siler. Ama log dosyasnn bykl klmez. DBCC SHRINKDATABASE(hb, 25) -- Log dosyalarn %25'i bo kalacak kltr??

Options > Auto Close = DB'yi kullanan program kalmaynca otomatik kapatr. Default false'tur.

aka

Options > Auto Create Statistics = altrma plann belirlerken istatistikleri kullanr. Hangi indeksleri kullanacan istatistiklere bakarak karar verir, baka yolu yoktur. Tercih edilen deeri true'dur, bylece istenen index'leri kullanr. Options > Auto Shrink = Kendiliinden shrink eder. Bu deer false braklr. Options > ANSI NULL Default = null ile null' karlatrrsak birbirine eit midir ? SELECT * FROM Stok WHERE null = null // null != null ise dndrmez SELECT * FROM Fatura WHERE BelgeNo is NULL // null != null olsa da dndrr Koul false dner, neden ? null'n null'a eit olup olmad bilinmez. ANSI standardnda null = null false'tur. Ancak, MS baz durumlar iin null = null karlatrmasn true kabul edebilir. Bu ANSI NULL Default ve ANSI NULL Enable ile yaplr. Bu durumdan sknt ekmek iin karlatrmada operatr olarak eittir yerine "is" kullanmak gerekir.

Options > Database Read-Only: db'den sadece okuma yaplr. Options > Restrict Access: Restricted User'da yalnzca admin'ler eriime sahiptir. Default MULTI_USER'dr. ALTER DATABASE dbName SET READ_ONLY

VER TRLER Text veri tr yn (blog) eklinde veri tutar. Bildik ekilde Text'ten okuma yapamayz. Bunun yerine varcharmax artk kullanlyor. binary: 8K'ya kadar bin data tutar. Resim etc... burada tutulabilir. varbinary: bizim kullandmz kadar byte kullanyor. image: 2GB'ye kadar binary data tutar. Binary verilerin kendisini db'de tutalm, yoksa bir varchar alanda sadece dosyann path'ini mi tutalm ? sql_variant trne her trde veri yazlabilir ancak yazarken trn bildirmek gerekir. Kullanlmas pek tavsiye edilmeyen bir alandr. timestamp: db baznda unique bir ID retmekte kullanlr. Primary Key olarak kullanlabilir. DB baznda Unique olduunu garanti eder. uniqueidentifier: Dnyada tek bir rakam gerekiyorsa retir. Bir kolonun trn uniqueidentifier yapmamz deer retmesi iin yeterli deil. Default value or binding olarak default'una newid() yazmak gerekli. xml veri tr: xml verisini dorudan tutar. xml veriyi indeksleyebilir. u node'daki veriyi getir diyebiliriz. SQL Server'da bir satrda tutulabilecek en byk veri 8000 byte'tr. varchar(MAX): Bu veri trnde 2GB'ye kadar veri tutulur. Text veri tr yerine kullanlmaktadr.

27 Temmuz 2008 SQL Server verileri 8K'lk page'lerde tutar. 8 tane 8 page'ten oluan toplulua 1 extend denir.

Bir satrlk veri bir page'in ierisinde saklanmak zorunda. Bu sebeple veri 8192K'dr. Bunun bir ksm internal ilere ayrlr. 8000K kalr. Bir page'de tek bir satrn saklanmas mecburi deildir. 3000'er byte'lk 2 satr bir page'te tutulabilir. Bu durumda 2000 byte da boa gitmi olur nk page'ler blnemez. DB'yi yarattmzda sql file'da ok sayda page ve extend oluturulur. Her bir page'in bir numaras var, indekslemede her bir verinin hangi page'in satrnda olduu tutuluyor. Sadece tablolar deil tm nesneler page'lerde tutulur. Database page'lerden oluur. Tm server' ilgilendiren veriler Master DB'sinde tutulur. Bu tabloya dorudan eriemeyiz. sys emasndaki sysdatabases view'i ile ancak ieriini grebiliriz. SELECT * FROM sys.sysdatabases

Belirtilen spesifik DB'deki tm nesneleri grmek iin: SELECT * FROM sys.sysobjects // bu bir view'dir ancak

Bir nesne yaratacaksak nce sysobjects tablosuna bakarz, o nesneden zaten var m diye varsa olan ya drop ederiz ya da o nesneyi yaratmayz. Kolonlarn tanmlarnn bulunduu tablo: SELECT * FROM sys.syscolumns Bir nesnenin id'sini SELECT object_id('Stok') Stok tablosunun kolonlarn bulmak iin: SELECT * FROM sys.syscolumns WHERE id = object_id('Stok') // Stok tablosunun id'sini bulur ve o tabloye fetch eder. Buradaki id tablonun id'sidir. Yaratlan bir tablodaki AUTO_INCREMENT UNIQUE id ile kartrlmamaldr. Tablonun id'si aslnda bir metadata'dr. Metadata veriyi tanmlayan veridir. SQL Server'da zaman zaman metadata'ya erimek gerekir. rnein, bazen programatik olarak yeni bir tablo oluturmak ya da kolon eklemek gerekebilir. te, bu gibi durumlarda nce gidip metadata'ya baklr, sonucuna gre tablo/kolon yaratlr ya da yaratlmaz (sorgu sonucu: ya zaten ayn tablodan varsa) SELECT DISTINCT xtype FROM sys.sysobjects Burada, sysobjects tablosundaki trler fetch edilir. Database id'si aadaki gibi alnabilir: SELECT db_id() SELECT db_id('hb') // Parametre ile db ismi geilebilir. Geilmezse o anda aktif olan verir. // Stok tablosunun id'sini dndrr.

Makinamzda oluturduumuz aadaki gibi fetch edilebilir:

tm

prosedr,

fonksiyon,

trigger,

view

etc.

SELECT * FROM sys.syscomments CREATE proc up_StokBul @ArananStokAd varchar(100) AS SELECT * FROM Stok WHERE StokAd LIKE @ArananStokAd + '%' up_StokBul 'RAM' Stok tablosuna ait prosedrler nasl bulabiliriz? SELECT * FROM sys.syscomments WHERE text like'%Stok%' CREATE PROC up_StokEkle @StokKod char(10), @StokAd varchar(100) AS INSERT INTO Stok VALUES (@StokKod, @StokAd) dbCommand.Parameters.Add(@StokKod, DbType.VarChar).Value = textbox1.text IDENTITY alanlar integer olabilir veya noktadan sonra sfr uzunlukta olmak koulu ile decimal ve numeric de IDENTITY alann veri tr olarak kullanlabilir. Sadece tek bir alana IDENTITY zellii eklenebilir. DELETE tabloadi DROP tabloadi => Tablonun iindeki tm data'y siler. => Tablonun kendisini siler.

Identity deerlerini nasl sfrlarm: TRUNCATE TABLE tabloadi Sildii data'lar delete'in yapt gibi log transaction'na yazmaz, bu yzden delete'ten ok daha hzl alr. Truncate ile IDENTITY alan da sfrlanr. TRUNCATE tablodaki tm data'y siler, birlikte WHERE clause'u kullanlamaz.

varchar(MAX) tek satrda 8K snrndan etkilenmez. Bu veri trnde data'nn saklanma ekli farkldr. char(10)'a kadarlk alanlarn primary key olmas mantkl ancak daha byk string alanlarn primary key olmas yavalamaya sebep olacandan mantkl deildir. Foreign Key Relationships menusnde Check Existing Data on Creating kk ile ilikinin restrict olup olmayacan belirleriz. rnein, Musteri tablosundaki irsaliyeNo 1'dir, fakat irsaliye tablosunda IrsaliyeNo'su 1 olan bir irsaliye yoktur. te, eer bu k Yes olarak seildiyse bu duruma msaade etmeyecektir ancak No ise geerli olacaktr. Ancak, ilgili musteri'yi silmeden ilgili irsaliyeyi silmemiz mmkn olacaktr.

Fatura - rsaliye tablolarnda iliki var. Faturann rsaliyeNo alan rsaliye'nin rsaliyeNo alann gsteriyor. Bir irsaliyeyi sildiimde bu irsaliye ile ilgili tm faturalarnda otomatik silinmesini istiyorsam ilikiyi kurarken aadaki gibi kurmam gerekir: ALTER TABLE Fatura WITH NOCHECK ADD CONSTRAINT FK_FaturaIrsaliye FOREIGN KEY(IrsaliyeNo) REFERENCES Irsaliye(IrsaliyeNo) ON DELETE CASCADE Burada ON DELETE CASCADE ilemi istediimiz gibi gerekletirmemizi salar. Foreign Key Relations menusnde INSERT and UPDATE Specification ksmnda Delete Rule ve Update Rule'lar ile cascading'i salayabiliriz. Bylece gsterilen deitiinde gsteren de deiiyor, silindiinde de silinir.

Object Explorer'da tablolarda Constraint > New Constraint diyerek birtakm kstlar belirtebiliriz. rnein, Fatura tablosu iin toplam sfrdan kk olamaz kst konulabilir: Bunun iin Expression'a [Toplam]>(0) demeliyiz. ALTER TABLE Fatura ADD CONSTRAINT C_Toplam CHECK Toplam > 0 ALTER TABLE Fatura ADD CONSTRAINT C_GenelToplam CHECK GenelToplam < 10000 // 10000 YTL zerinde fatura kesilmesini engeller.

Kstlar (Constraint) veri girilirken uyulmas gereken temel kstlar belirtilir. rn girilirken adet sfrdan kk olmasn gibi. Foreign key ve primary key de birer constraint olmakla beraber o alana girilecek verilere getirilen snrlamalar da ayn trde birer ksttr. Varolan Constraint'e sa tkla > modify > Enforce for INSERTs and UPDATEs false yaplrsa kstlar diable edilir. Bu ilem script ile aadaki gibi yaplabilir: ALTER TABLE Fatura NOCHECK CONSTRAINT CK_Fatura

GEC TABLOLAR Sehirler tablomuz var ancak bize yalnzca marmara blgesindeki ehirlerden oluan bir tablo gerekiyor. Bunu varolan sehirler tablosundan otomatik olarak aadaki script ile oluturabiliriz: SELECT * FROM Sehir SELECT SehirKod, SehirAd FROM Sehir WHERE BolgeNo = 1 Yukardaki ilem sadece sonucu getirir. Sonucu baka bir tabloya almak istersek? Bir yntem: CREATE TABLE MarmaraBolgesi ( SehirNo int NOT NULL PRIMARY KEY, SehirAd varchar(50) NOT NULL, ) INSERT INTO MarmaraBolgesi SELECT SehirNo, SehirAd FROM Sehir WHERE BolgeNo = 1

Yukardaki script aadaki ekilde daha ksa ekilde yaplabilir: SELECT SehirNo, SehirAd INTO MarmaraBolgesiSehirleri FROM Sehir WHERE BolgeNo = 1 (SELECT INTO kalb) Bu ekilde yaratlan tablolarda PK'y bizim sonradan vermemiz gerekir. Yukardaki ilemde kalc bir tablo oluturmak zorunda kaldk. Bunu geici bir tablo ile zmek iin: Yukardaki script'te tablo adnn bana bir # koyduumuzda tablo geici bir tablo olarak yaratlr: SELECT SehirNo, SehirAd WHERE BolgeNo = 1 INTO #MarmaraBolgesiSehirleri FROM Sehir

Yaratlan bu geici tabloya Object Browser'da kendi veritabanmzdaki tablolarn arasnda gremeyiz nk bu tablo System Databases'da tempdb altna konulur. Bir temp tablo aadaki gibi de yaratlabilir: CREATE TABLE #EgeBolgesi ( SehirKod int NOT NULL SehirAd varchar(50) NOT NULL )

PRIMARY KEY,

Geici tablo session boyunca yaacaktr. Geici tablonun yaratld pencere haricinde dier pencereler bu geici tabloyu gremezler. Her bir pencere bir process'dir ve bir processId ile temsil edilir ve her bir pencere aslnda ayr bir connection'dr. Tm process'ler sys.sysprocesses view'inde grntlenebilir. SELECT * FROM sys.sysprocesses u andaki processId'imizi aadaki script ile alabiliriz: SELECT @@spid

DATA MANIPULATION LANGUAGE (DML) SELECT komutu:


Genel sentaks: SELECT <kolonListesi> FROM <tabloadi> [WHERE] [kolonAdi] [operator] [kosul] SELECT * FROM Fatura WHERE GenelToplam > 5000 AND FaturaNo < 5 SELECT * FROM Fatura WHERE Tarih >= '20080601' // 6. aydan sonraki faturalar

Buradaki YYYY/AA/GG format standarttr ve makinann lokaline bal deildir. ayet, GG/AA/YYYY formatnda girersek baka makinalarda AA/GG/YYYY olabilir, format uyumayacaktr ve hataya sebep olacaktr. Kolonlara takma isimler verebiliriz: SELECT FaturaNo AS No, MusteriNo AS Musteri FROM Fatura SELECT sorgusunda yeni bir temp kolona hesaplanm bir deer yerletirebiliriz: SELECT FaturaNo AS No, MusteriNo AS Musteri, GenelToplam, GenelToplam * 0.1 AS NakliyeUcreti FROM Fatura Kolon isimlerinde boluk karakteri kullanmak istersek: SELECT FaturaNo AS [Fatura No], MusteriNo AS [Musteri No], GenelToplam, GenelToplam * 0.1 AS [Nakliye Ucreti] FROM Fatura Nesne isimlerinde de (rnein tablo yaratrken tablo isminde) boluk karakteri kullanabiliriz. SQL Server'a dair keyword olarak kullanlan kelimeleri identifer olarak kullanmak istersek bu kelimeleri keli parantez ierisinde yazarak kullanabiliriz. DB'den export ilemi object explorer'da db'ye sa tkla > Export ile yaplr. Tablo da aktarlabilir, bir sorgu sonucu elde edilen data'da aktarlabilir. SELECT @@version => Sql Server'n versiyonunu getirir.

Tr dntrme ve kolonlar toplama ilemi: SELECT BelgeNo + cast(MusteriNo as varchar) as [Belge ve Musteri No], GenelToplam FROM Fatura SELECT BelgeNo + ' ' + cast(MusteriNo as varchar) as [Belge ve Musteri No], GenelToplam FROM Fatura SELECT 'Belge No: ' + BelgeNo + ' Musteri No: ' + cast(MusteriNo as varchar) AS [Belge ve Mteri No] FROM Fatura Excel'e export edeceim ve bulunmayan ek bir tabloyu fetch etmek gerekiyor: SELECT 'Belge No: ' + BelgeNo + ' Musteri No: ' + cast(MusteriNo as varchar) AS [Belge ve Mteri No], '' AS ndirim FROM Fatura Bu sorguda + konan yerlere virgl konursa her birini ayr bir kolonda gsterir.

Tarih bilgisini dntrmek iin convert() fonksiyonu kullanlr: SELECT convert(varchar, Tarih, 103) FROM Fatura Burada 103 baklabilir. tarihin formatn belirtir. MSDN'den bu format deerlerine

2 Austos 2008 Bir tablonun iinde ne kadar veri olduu nasl grlr ? Table Properties > General > Row Count ile renilebilir. SELECT 'AAA' FROM Fatura yaznca ne olur? -- Fatura tablosunun tm satrlarn bir dng ile iterate eder ve sras ile her satra 'AAA' yazar. SELECT 'AAA', FaturaNo FaturaNo'sunu dndrr. FROM Fatura => Her satr iin 'AAA' yazarak

SELECT 'AAA', FaturaNo FROM Fatura WHERE GenelToplam > 100 // Burada, tm satrlar gezer ve koula uyan satrlar dndrr. SELECT 'Fatura Numaras: ' AS No, FaturaNo FROM Fatura => Virglle ayrlanlarn hepsi birer kolondur. Bu kolonlar db'deki kolonlar da olabilir, o anda bizim elle eklemekte olduumuz kolonlar da olabilir. SELECT 'Fatura Numaras: ', FaturaNo, 'Genel Toplam: ' AS [Genel Toplam], GenelToplam, GenelToplam * 0.9 AS ndirimliTutar FROM Fatura WHERE GenelToplam > 100 SELECT StokKod, StokAd, StokFiyat * 1.18 AS [KDV'li Fiyat] FROM Stok WHERE Kdv = 18 // KDV'si %18 olan stoklarn StokKod, StokAd ve KDV'li fiyatlarn fetch eder. SELECT StokKod, StokAd, StokFiyat * (100 + KDV) / 100 AS [KDV'li Fiyat] FROM Stok // Burada KDV kolonundaki veri kullanld. KDV'li fiyat noktadan sonra iki hane ile kstlamak iin: * (100 + KDV) / 100 AS

SELECT StokKod, StokAd, cast(StokFiyat decimal(10,2)) AS [KDV'li Fiyat] FROM Stok Cast'in sentaks: cast(<Veri> as <YeniTr>)

Stok tablosunda aklamas null olmayanlar dndr:

SELECT * FROM Stok WHERE Aciklama IS NOT NULL Dikkat!: NULL karlatrmas karlatrma operatrleri ile yaplmaz. Bu konuya nceden deinildi. SELECT * FROM Stok WHERE Acklama IS NOT NULL AND StokFiyat > 100 // Aklamas var ve fiyat 100 YTL'nin zerinde SELECT * FROM Stok WHERE (StokFiyat * (100 + Kdv) / 100) >= 140 KDV'li fiyat 140 YTL ve zerindeki rnleri getirir. SELECT *, cast(StokFiyat * (100 + Kdv) / 100 AS decimal(8,2)) AS [KDV'li Fiyat] FROM Stok WHERE (StokFiyat * (100 + Kdv) / 100) > 140 Miktar 20 ile 50 arasndaki olan rnler:

SELECT * FROM Stok WHERE Miktar >= 20 AND Miktar <= 50 Ya da SELECT * FROM Stok WHERE Miktar BETWEEN 20 AND 50 BETWEEN belirtilen deerlerdeki eitlii de fetch eder.

JOIN Kullanmna rnek: -- StokAd, StokKod ve StokGrubunu fetch et ! SELECT StokKod, StokAd, LEFT(StokKod, 3) AS StokGrubu FROM Stok -- Yanl SELECT StokKod, StokAd, UrunGrupAd AS StokGrubu FROM Stok, UrunGrup -HATA: Burada her bir StokKod'unu tm UrunGruplar ile eletirmi yani kartezyen bir arpm yapm, 10 satra 8 satrsa 80 satr dndrr gibi => ie iki dng SELECT StokKod, StokAd, UrunGrupAd AS StokGrubu FROM Stok, UrunGrup WHERE LEFT(StokKod, 3) = UrunGrupKod -- Yukardaki yntem eski yntem. Artk bu ilem JOIN ile yaplyor. SELECT StokKod, StokAd, UrunGrupAd AS StokGrubu FROM Stok JOIN UrunGrup ON LEFT(StokKod, 3) = UrunGrupKod -- Burada JOIN ile dier tablo eklenir ve ON birletirme koulunu belirtir. -- WHERE normal bir koul iin kullanlr, ON ise birletirme koulunu belirtmek iin kullanlr. --------- * ----------- Tablolar JOIN edilirken bir mecburiyet olmamakla beraber genelde JOIN'ler FOREIGN KEY'ler ile birbirine balanr. Object Explorer'dan bir tabloyu seerek ve open table diyerek Show Diagram Pane'e basarz. Otomatik olarak FOREIGN KEY'lerden JOIN'leme ilemi yaplr. Diagram Pane'de FOREIGN KEY'lerden birbirine JOIN'lenmi tablolardan hangi field'lerdeki verileri istediimizi seebiliriz. Sonucunda uygun script'i kendisi retecektir.

SELECT Stok.StokKod, Stok.Stokad, UrunGrup.UrunGrupAd FROM Stok INNER JOIN StokUrunGrup ON Stok.StokKod = StokUrunGrup.StokKod INNER JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod Bu sorgunun eski usul yapl aadaki gibidir: SELECT Stok.StokKod, Stok.StokAd, UrunGrup.UrunGrupAd FROM Stok, StokUrunGrup, UrunGrup WHERE Stok.StokKod = StokUrunGrup.StokKod AND StokUrunGrup.UrunGrup UrunGrup.UrunGrupKod

-- simleri ksaltabiliriz ancak ksaltrsak artk her yerde bu ksaltmalar kullanmamz gerekir. Tablo ksaltmalar FROM'dan sonra belirtilir.

SELECT s.StokKod, s.StokAd, ug.UrunGrupAd FROM Stok AS s, StokUrunGrup AS sug, UrunGrup AS ug WHERE s.StokKod = sug.StokKod AND sug.UrunGrup = ug.UrunGrupKod -- Ksaltma ile JOIN kullanarak yazm: SELECT S.StokKod, S.StokAd, Ug.UrunGrupAd FROM Stok AS S JOIN StokUrunGrup AS Sug ON S.StokKod = Sug.StokKod JOIN UrunGrup AS Ug ON Sug.UrunGrup = Ug.UrunGrupKod

Genel JOIN Sentaks: SELECT <kolon listesi> FROM <Tablo> JOIN <Birletirilecek Tablo> ON <Birletirme Koulu>
Stokun rnGrupAd'n fetch etmek iin StokUrunGrup tablosunu UrunGrup tablosuna ulamak iin ara tablo olarak kullanrz. Hatrlarsak StokUrunGrup tablosuna Stok ve UrunGrup tablolarnn bire ok ilikisi var ve dolaysyla Stok ve UrunGrup tablolarnn birbirlerine oka ok ilikisi var. oka ok iliki olan tablolarda bir tablodan dierine erimek iin ara tabloyu kullanmak gerekir. Yalnzca JOIN yazarsak default olarak INNER JOIN kabul edilir. Snf almas: Tm msterilerin adlarn, bulunduklar sehir adlarn ve bolge adlarn fetch edin.

SELECT Musteri.MusteriAd, Sehir.SehirAd, Bolge.BolgeAd FROM Musteri JOIN Sehir ON Musteri.SehirKod = Sehir.SehirNo JOIN Bolge ON Sehir.BolgeNo = Bolge.BolgeNo UNIQUE VE INDEX Bir field'in deeri unique olsun istiyorsak o field iin bir unique index koymamz gerekir. Script'i aadaki gibidir: CREATE UNIQUE NONCLUSTERED INDEX [UO_MusteriTurNo] ON [dbo].[MusteriTur] ([MusteriTrAd]) Tasarmsal olarak Object Explorer'dan Tablo'nun alt detaylarndaki Indexes'a sa tklayarak New Index'i sememiz gerekir. Buradan Unique olmasn ve hangi field'in unique olacan belirtiriz. Unique kst koymak ile index koymak neredeyse ayn ey !

SINIF ALIMASI: Mterinin adn, tr adn, sehir adn ve bolge adn fetch edin: SELECT Musteri.MusteriAd, MusteriTur.MusteriTrAd, Sehir.SehirAd, Bolge.BolgeAd FROM Musteri JOIN MusteriTur ON Musteri.MusteriTuru = MusteriTur.MusteriTurNo JOIN Sehir ON Musteri.SehirKod = Sehir.SehirNo JOIN Bolge ON Sehir.BolgeNo = Bolge.BolgeNo

Ayn bilgileri bakiyesi eksi olanlarla yani bize borlu olanlarla geri dndr: SELECT Musteri.MusteriAd, MusteriTur.MusteriTrAd, Sehir.SehirAd, Bolge.BolgeAd, Musteri.Bakiye FROM Musteri

JOIN MusteriTur ON Musteri.MusteriTuru = MusteriTur.MusteriTurNo JOIN Sehir ON Musteri.SehirKod = Sehir.SehirNo JOIN Bolge ON Sehir.BolgeNo = Bolge.BolgeNo WHERE Musteri.Bakiye < 0

-- MusteriAd, FaturaTarihi, ToplamTutar gsteren sorgu, Toplam Tutarda -- azalana gre srala SELECT Musteri.MusteriAd, Fatura.Tarih, Fatura.GenelToplam * ((100 + Fatura.Kdv) / 100) AS [Toplam Tutar] FROM Fatura JOIN Musteri ON Fatura.MusteriNo = Musteri.MusteriNo ORDER BY [Toplam Tutar] DESC 3 Austos 2008 imdiye kadar grdmz JOIN'ler INNER JOIN'lerdi. Musteri tablosuna IBM Corp koysak ve bu irket ABD'de olduundan ehir giremiyoruz. Dolaysyla sorgudaki Musteri.SehirKod = Sehir.SehirKod kouluna uymad iin INNER JOIN bu kayd getirmez. Sorguyu LEFT OUTER JOIN yaparsak her iki tablodan bu koulu salayanlar dndrr art soldaki tablodan bu koulu salamayan kaytlar da dndrr. SELECT Musteri.MusteriNo, Musteri.MusteriAd, Sehir.SehirAd FROM Musteri LEFT OUTER JOIN Sehir ON Musteri.SehirKod = Sehir.Kod Burada soldaki tablo Musteri, sadaki tablo Sehir'dir. [JOIN'in solu ve sa olarak baklabilir.] SELECT Musteri.MusteriNo, Musteri.MusteriAd, Sehir.SehirAd FROM Musteri LEFT OUTER JOIN Sehir ON Musteri.SehirKod = Sehir.SehirNo SELECT Musteri.MusteriNo, Musteri.MusteriAd, Sehir.SehirAd FROM Sehir LEFT OUTER JOIN Musteri ON Musteri.SehirKod = Sehir.SehirNo SELECT Musteri.MusteriNo, Musteri.MusteriAd, Sehir.SehirAd FROM Sehir RIGHT OUTER JOIN Musteri ON Musteri.SehirKod = Sehir.SehirNo OUTER JOIN, INNER JOIN'i kapsar. OUTER JOIN ettiimiz yne bal olarak (LEFT, RIGHT) o ynde koula uymayan kaytlar da getirir. Sadece OUTER JOIN yazamayz, LEFT ya da RIGHT olarak belirtmemiz gerekir. LEFT veya RIGHT yazdysak OUTER yazmak zorunlu deil. FULL OUTER JOIN'de ise hem soldaki hem de sadaki tabloda koulu salayan ve salamayanlar getirir:

SELECT Musteri.MusteriNo, Musteri.MusteriAd, MusteriTur.MusteriTurAd FROM Musteri FULL OUTER JOIN MusteriTur ON MusteriTur.MusteriTurNo = Musteri.MusteriTuru Eskiden LEFT JOIN iin kouldaki = operatr *= olarak, RIGHT JOIN iin =* operatrleri kullanlrd. SQL Server 2005 artk bu sentaks desteklememektedir.

-- Aadaki gibi bir karlatrma da olabilir. Yazdmz ey mutlaka kolonlar olacak demek deil, sabit input girebiliriz. SELECT Musteri.MusteriNo, Musteri.MusteriAd, MusteriTur.MusteriTurAd FROM Musteri JOIN MusteriTur ON Musteri.MusteriAd > 'H' SQL Cmleciine verilen koul mutlaka kolon isimlerinden olumak zorunda deildir. Koul olarak ON 1 = 1 dahi diyebiliriz. Bir tabloyu kendisine JOIN'lemek iin:

SELECT p1.PersonelAd, p2.PersonelAd FROM Personel AS p1 JOIN Personel AS p2 ON p1.BagliOlduguKisi = p2.SicilNo Burada ayn tabloyu iki kere kullandmz iin takma ad belirtmemiz zorunludur. Bir tablonun kendi kendine JOIN'lenmesine Self-Join denir. OUTER JOIN'de NULL olan hcrelere 'Mdr yok' yazsn istiyorsak:

SELECT p1.PersonelAd AS Eleman, CASE WHEN p2.PersonelAd IS NULL THEN 'Mdr Yok' ELSE p2.PersonelAd END AS Mudur FROM Personel AS p1 LEFT JOIN Personel AS p2 ON p1.BagliOlduguKisi = p2.SicilNo CASE WHEN <Kosul ifadesi> IS NULL THEN <Sonuc1> ELSE <Sonuc2> END -- Mteri alacakl m borlu mu, yazdr SELECT Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye, CASE WHEN Musteri.Bakiye > 0 THEN 'Alacakl' WHEN Musteri.Bakiye < 0 THEN 'Borlu' ELSE 'Bakiyesi Temiz' END AS [Bakiye Sonucu] FROM Musteri

SELECT Personel.PersonelAd, CASE WHEN Personel.Bolum = 1 THEN 'Ynetim' WHEN Personel.Bolum = 2 THEN 'stanbul' WHEN Personel.Bolum = 3 THEN 'Ankara' END AS [Personel Blm] FROM Personel -- Alternatif yazm: Bu yazmda dorudan eitlik gerekiyor. Kktr ya da byktr diyemeyiz: SELECT PersonelAd, CASE Bolum WHEN 1 THEN 'Ynetim'

WHEN 2 THEN 'stanbul personeli' WHEN 3 THEN 'Ankara personeli' ELSE 'Dier' END AS [Personel Blm] FROM Personel Kolon dndrdmz her yerde CASE komutunu kullanabiliriz.

--Her bir musteriye tm faturalarda satlan rnler --istenen bilgi MusteriAd, FaturaNo, FaturaTarih, StokAd, SatlanAdet, BirimFiyat, ToplamTutar SELECT Musteri.MusteriAd, Fatura.FaturaNo, Fatura.Tarih, Stok.StokAd, FaturaDetay.Adet, FaturaDetay.BirimFiyat, FaturaDetay.Tutar FROM Musteri JOIN Fatura ON Fatura.MusteriNo = Musteri.MusteriNo JOIN FaturaDetay ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN Stok ON Stok.StokKod = FaturaDetay.StokKod

-- Faturalarda maln gnderilecei nakliyesehir ile mterinin bulunduu sehirin farkl olduu faturalar -- bulan sorgu -- FaturaNo, FaturaTarihi, MusteriAd, Musteri SehirAd, Nakliye edilen sehir ad SELECT Fatura.FaturaNo, Fatura.Tarih, Musteri.MusteriAd, s_m.SehirAd AS [Musteri Sehir], s_n.SehirAd AS [Nakliye Sehir] FROM Fatura JOIN Musteri ON Musteri.MusteriNo = Fatura.MusteriNo JOIN Sehir AS s_m ON s_m.SehirNo = Musteri.SehirKod JOIN Sehir AS s_n ON s_n.SehirNo = Fatura.NakliyeSehir WHERE s_m.SehirNo != s_n.SehirNo --Yukardaki rnein ztt, nakliye ehir ile mteri ehir ayn ise: SELECT Fatura.FaturaNo, Fatura.Tarih, Musteri.MusteriAd, s_m.SehirAd AS [Musteri Sehir], s_n.SehirAd AS [Nakliye Sehir] FROM Fatura JOIN Musteri ON Musteri.MusteriNo = Fatura.MusteriNo JOIN Sehir AS s_m ON s_m.SehirNo = Musteri.SehirKod JOIN Sehir AS s_n ON s_n.SehirNo = Fatura.NakliyeSehir WHERE s_m.SehirNo = s_n.SehirNo

-- Farkl blgelere naklettirenleri bul ! SELECT Fatura.FaturaNo, convert(varchar, Fatura.Tarih, 103) AS [Fatura Tarihi], Musteri.MusteriAd, s1.SehirAd AS [Musteri Sehir], s2.SehirAd AS [Nakliye Sehir], b1.BolgeAd AS [Musteri Blge], b2.BolgeAd AS [Nakliye Blge] FROM Fatura JOIN Musteri ON Musteri.MusteriNo = Fatura.MusteriNo JOIN Sehir AS s1 ON s1.SehirNo = Musteri.SehirKod JOIN Sehir AS s2 ON s2.SehirNo = Fatura.NakliyeSehir JOIN Bolge AS b1 ON b1.BolgeNo = s1.BolgeNo

JOIN Bolge AS b2 ON b2.BolgeNo = s2.BolgeNo WHERE s1.BolgeNo != s2.BolgeNo

-- Tm faturalarn No'su, tarihi, Msteri Ad, SatisPersonelAd, FaturaGenel Toplam, Fatura.Toplam, -- Fatura.Toplam' 100 YTL'den fazla ise %4' prim altnda ise %3 prim ver SELECT Fatura.FaturaNo, Fatura.Tarih, Musteri.MusteriAd, Personel.PersonelAd, Fatura.GenelToplam, Fatura.Toplam, CASE WHEN Fatura.Toplam > 100 THEN ((Fatura.Toplam * 0.04) + Fatura.Toplam) ELSE ((Fatura.Toplam * 0.03) + Fatura.Toplam) END AS Prim FROM Fatura JOIN Musteri ON Musteri.MusteriNo = Fatura.MusteriNo JOIN Personel ON Personel.SicilNo = Fatura.SatisEleman

16 Austos 2008 JOIN'in ortaya kmasnda nemli olan eylerden biri nceden FROM'dan sonra tm tablo isimleri yazlrd ve tablolar birbirlerine JOIN eklinde bir keyword olmad iin WHERE clause'unda birletirilirdi ve WHERE clause'unda tablo birletirme koullar ile gerek koullar birbirlerine karrlard. JOIN'de ise WHERE clause'unda yalnzca gerek koullar yer alyor, birletirme koullar JOIN'den sonra gelen ON clause'unda belirtiliyor. FOREIGN KEY ile JOIN'lemek mecburi deildir. Ama daha mantkl olandr.

SELECT s.StokAd, ug.UrunGrupAd FROM Stok s, UrunGrup ug yazm ile SELECT s.StokAd, ug.UrunGrupAd FROM Stok s, UrunGrup ug WHERE 1 = 1 yazm ile SELECT s.StokAd, ug.UrunGrupAd FROM Stok s CROSS JOIN UrunGrup ug yazm ayndr. Buna Cross Join denir.

-- Hangi rnler birbirleri ile satlmlar. SELECT fd1.StokKod, fd2.StokKod FROM FaturaDetay AS fd1 JOIN FaturaDetay AS fd2 ON fd1.FaturaNo = fd2.FaturaNo AND fd1.StokKod > fd2.StokKod

SORGULARDA AGGREGATION(SORGULARDA ZETLEME)


SELECT Count(*) FROM Musteri Count(*) ile tm satrlar saylr. Count()'a kolon ismi verebiliriz. Bu durumda NULL olmayan kolondaki kayt saysn dndrr.

-- Bir faturada bir kerede en fazla ka liralk al veri yaplm SELECT Max(Toplam) FROM Fatura SELECT Min(Toplam) FROM Fatura SELECT Avg(Toplam) FROM Fatura -- Toplamda yaplan alveri tutar SELECT Sum(Toplam) FROM Fatura -- Her bir faturada (faturadetay) ka kalem rn satlm SELECT FaturaNo, Count(*) FROM FaturaDetay GROUP BY FaturaNo

-- Her bir faturada kesilen en byk tutarlar bul -- AKA Kesilen her bir faturadaki en yksek tutarl sat getir. SELECT FaturaNo, Max(Tutar) FROM FaturaDetay GROUP BY FaturaNo

-- Max ve min ne kadarlk sat yaplm SELECT FaturaNo, Max(Tutar) AS [En pahal sat], Min(Tutar) AS [En ucuz sat] FROM FaturaDetay GROUP BY FaturaNo Books Online'dan Aggregate Functions olarak ara. Hepsini gsterir. zetlenmi veri zerinde koul koymak iin HAVING kullanlr. WHERE gruplanma yaplmam satrlar zerinde kstlama Gruplanma yaplm satrlar zerinde HAVING ile kstlama yaplr. yapar.

-- Her bir faturada ka kalem mal satlm, kesilen kalem says 2'den byk ise getir. SELECT FaturaNo, Count(*) FROM FaturaDetay GROUP BY FaturaNo HAVING Count(*) > 2

-- Bir faturada kalem baznda birim fiyat 100 TL'nin zerinde ka sat yaplm, -- kalem says ikinin zerindekileri getir. SELECT FaturaNo, Count(*) AS [Fatura Adeti] FROM FaturaDetay WHERE Tutar >= 100 GROUP BY FaturaNo HAVING Count(*) > 2

-- Blge ve ehir baznda ka mteri var // Sehir saysn count etti, -- bolge baznda toplam gstermiyor. SELECT b.BolgeAd, s.SehirAd, Count(*) AS [Musteri Sayisi] FROM Musteri AS m JOIN Sehir AS s on m.SehirKod = s.SehirNo JOIN Bolge b on s.BolgeNo = b.BolgeNo GROUP BY b.BolgeAd, s.SehirAd ORDER BY b.BolgeAd, s.SehirAd

-- Tm bilgileri getirmek iin, sadece iteki gruba gre deil, tamamna gre hesaplar SELECT b.BolgeAd, s.SehirAd, Count(*) AS [Musteri Sayisi] FROM Musteri AS m JOIN Sehir AS s on m.SehirKod = s.SehirNo JOIN Bolge b on s.BolgeNo = b.BolgeNo GROUP BY b.BolgeAd, s.SehirAd WITH ROLLUP ORDER BY b.BolgeAd, s.SehirAd GROUP BY ierisinde kullanlacak koul SELECT ierisinde belirtilmek zorundadr. 17 Austos 2008 Bir aggregate fonksiyonu arldnda ayn sorguda bir kolonun dndrlmesi mantkszdr. Aggregate fonksiyonu tek bir sonu dndrrken kolondan ka tane varsa o kadar dnecektir ve her birinde ayn aggregate fonksiyonunun geri dn deeri olacaktr. ORDER BY'da belirtilen expression'nn kolon olarak SELECT'te belirtilmesi gerekli deildir. GROUPING(kolonad) => gerekte varolan kolonlara 0, zetleme iin kendisinin rettii kolonlara 1 deerini geer.

-- En ok borlu olan mteriyi getir. -- MusteriKod, Ad, bakiye SELECT Top 3 Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri ORDER BY Musteri.Bakiye ASC -- Bakiyesi en yksek ilk %30 musteriyi getir. SELECT Top 30 Percent Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri ORDER BY Musteri.Bakiye ASC UNION ile sonu set'leri birletirir.

SELECT SaticiAd, Adres, SehirNo FROM Satici UNION SELECT MusteriAd, Adres, SehirNo FROM Musteri

UNION kullanlan yerde kesiimi bulmak iin INTERSECT ya da ilkinde ikincisinde olmayanlar getirmek iin EXCEPT kullanlr. (Doal olarak INTERSECT'ler dnmez.) Birletirilen tablolarda ayn data'lar varsa UNION kendisi otomatik olarak DISTINCT uygular. Eer UNION'n otomatik olarak DISTINCT uygulamasn istemiyorsak UNION ALL kullanrz. EXCEPT Oracle'da yok, bunun yerine MINUS var.

-- Aggregation Fonksiyonlar SELECT Count(*) FROM Stok SELECT Sum(Toplam) FROM Fatura -- Belli gruplar zerinde aggregate (zet) sonular dndreceksek GROUP BY kullanlr. -- GROUP BY'a verilen ifade SELECT edilecek kolonlar arasnda daha nceden belirilmi -- olmaldr. SELECT StokKod, Sum(Adet) AS Adet FROM FaturaDetay GROUP BY StokKod -- 10 adetin zerinde yaplan satlar getir. Adlar ile getir. SELECT s.StokAd, Sum(fd.Adet) FROM FaturaDetay AS fd JOIN Stok AS s ON fd.StokKod = s.StokKod GROUP BY s.StokAd HAVING Sum(fd.Adet) > 5 SELECT b.BolgeAd, S.SehirAd, Count(*) FROM Musteri AS m JOIN Sehir AS s ON m.SehirKod = s.SehirNo JOIN Bolge AS b ON s.BolgeNo = b.BolgeNo GROUP BY b.BolgeAd, s.SehirAd WITH ROLLUP ORDER BY b.BolgeAd, s.SehirAd -- Biden en fazla alm yapan mterileri mterino ve msteriad'n en fazla bakiyesi olana gre -- bykten ke srala SELECT Musteri.MusteriNo, Musteri.MusteriAd FROM Musteri ORDER BY Bakiye DESC ----------------------------------------------------------------------------SELECT b.BolgeAd, S.SehirAd, Count(*) FROM Musteri AS m JOIN Sehir AS s ON m.SehirKod = s.SehirNo JOIN Bolge AS b ON s.BolgeNo = b.BolgeNo GROUP BY b.BolgeAd, s.SehirAd ORDER BY b.BolgeAd, s.SehirAd SELECT b.BolgeAd, S.SehirAd, Count(*) FROM Musteri AS m JOIN Sehir AS s ON m.SehirKod = s.SehirNo JOIN Bolge AS b ON s.BolgeNo = b.BolgeNo GROUP BY b.BolgeAd, s.SehirAd WITH ROLLUP ORDER BY b.BolgeAd, s.SehirAd SELECT b.BolgeAd, S.SehirAd, Count(*) FROM Musteri AS m JOIN Sehir AS s ON m.SehirKod = s.SehirNo

JOIN Bolge AS b ON s.BolgeNo = b.BolgeNo GROUP BY b.BolgeAd, s.SehirAd WITH CUBE -- WITH CUBE iteki grubun toplamn da gsterir. -- Bu rnek bir ile birden fazla ehirde varsa o ilelerinde gruplanm toplamn getirir. ORDER BY b.BolgeAd, s.SehirAd -- WITH CUBE, WITH ROLLUP' kapsar. -- rn grup baznda toplam ka liralk sat yaplm SELECT StokUrunGrup.StokKod, Sum(FaturaDetay.Tutar) FROM FaturaDetay JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod GROUP BY StokUrunGrup.StokKod SELECT UrunGrup.UrunGrupAd, Sum(FaturaDetay.Tutar) FROM FaturaDetay JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod GROUP BY UrunGrup.UrunGrupAd -- Hangi rn grubundan hangi ehire toplam sat nedir SELECT Sehir.SehirAd, UrunGrup.UrunGrupAd, Sum(Fatura.GenelToplam) FROM FaturaDetay JOIN Fatura ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod JOIN Sehir ON Sehir.SehirNo = Fatura.NakliyeSehir GROUP BY Sehir.SehirAd, UrunGrup.UrunGrupAd ORDER BY Sehir.SehirAd, UrunGrup.UrunGrupAd -- Sehirlerin her birinde toplam ne kadar sat yaplm SELECT Sehir.SehirAd, UrunGrup.UrunGrupAd, Sum(Fatura.GenelToplam) FROM FaturaDetay JOIN Fatura ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod JOIN Sehir ON Sehir.SehirNo = Fatura.NakliyeSehir GROUP BY Sehir.SehirAd, UrunGrup.UrunGrupAd WITH ROLLUP ORDER BY Sehir.SehirAd, UrunGrup.UrunGrupAd -- ehirlerde toplam rn satn, rnlerin kendisinin toplam sat tutarn ve her bir -- ehre her bir rn grubundan ne kadar sat yaplm SELECT Sehir.SehirAd, UrunGrup.UrunGrupAd, Sum(Fatura.GenelToplam) FROM FaturaDetay JOIN Fatura ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod JOIN Sehir ON Sehir.SehirNo = Fatura.NakliyeSehir GROUP BY Sehir.SehirAd, UrunGrup.UrunGrupAd WITH CUBE ORDER BY Sehir.SehirAd, UrunGrup.UrunGrupAd

SELECT Sehir.SehirAd, GROUPING(Sehir.SehirAd) AS [Is Aggregated], UrunGrup.UrunGrupAd, Sum(Fatura.GenelToplam) FROM FaturaDetay JOIN Fatura ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod

JOIN Sehir ON Sehir.SehirNo = Fatura.NakliyeSehir GROUP BY Sehir.SehirAd, UrunGrup.UrunGrupAd WITH CUBE ORDER BY Sehir.SehirAd, UrunGrup.UrunGrupAd

-- En ok borlu olan mteriyi getir. (Fakat sonuncu mterinin bor deerinde baka mteri varsa sadece -- bir tane dndrr. -- MusteriKod, Ad, bakiye SELECT Top 3 Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri ORDER BY Musteri.Bakiye ASC -- Bakiyesi en yksek ilk %30 musteriyi getir. SELECT Top 30 Percent Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri ORDER BY Musteri.Bakiye ASC -- En ok borlu olan mteriyi getir. (Sonuncu mterinin bor deerinde baka mteri varsa -- WITH TIES onlar da getirir SELECT Top 3 WITH TIES Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri ORDER BY Musteri.Bakiye ASC -- Deer olarak deiken verilebilir. DECLARE @value int SET @value = 5 SELECT TOP(@value) WITH TIES Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri ORDER BY Musteri.Bakiye ASC

-- DNAMK SORGULAR -DECLARE @StokKodu CREATE PROC StokBilgisiGetir @StokKodu varchar(100) AS SELECT * FROM Stok WHERE StokKod = @StokKodu StokBilgisiGetir 'RAM128' -- Peki ya bir tablonun adn bir deiken gibi almamz gerekirse: DECLARE @TabloAdi varchar(100) SET @StokKodu = 'Fatura' SELECT * FROM @TabloAdi -- Bu sorgu hata verir. Bu ilemin gereklemesi iin sorgunun -- dinamik oluturulmas gerekir. -- lk dinamik sorgu rnei DECLARE @TabloAdi varchar(100),@Sql varchar(1000) SET @TabloAdi = 'Fatura' SET @Sql = 'SELECT * FROM ' + @TabloAdi PRINT @Sql EXEC (@Sql)

-- ile aadaki ayndr DECLARE @TabloAdi varchar(100),@Sql varchar(1000) SET @TabloAdi = 'Fatura' -- PRINT @Sql EXEC ('SELECT * FROM ' + @TabloAdi) -- Dinamik sorgunun sp hali CREATE PROC TabloVerileriniGetir @TabloAdi varchar(100) AS EXEC ('SELECT * FROM ' + @TabloAdi) EXEC TabloVerileriniGetir 'Musteri' -- END OF Dinamik Sorgular --- SQL Server 2005 ncesinde TOP'a geilen deer statik olarak geilemiyordu. Ancak dinamik -- olarak geiliyordu. -- En az bir kere satlm olan rnler SELECT DISTINCT StokKod FROM FaturaDetay ORDER BY StokKod -- Union: sonu set'lerinin birletirilmesi CREATE TABLE Satici ( SaticiNo int PRIMARY KEY, SaticiAd varchar(100) Adres varchar(200), SehirNo int )

IDENTITY(1,1) NOT NULL,

INSERT INTO Satici VALUES('Arena A', 'Kemerburgaz Cad. No:23', 34) INSERT INTO Satici VALUES('Index A', 'Kla Cad. No:36', 34) INSERT INTO Satici VALUES('Karma A', 'Kou Cad. No:233', 35) SELECT * FROM Satici -- Tm ilikide olduumuz firmalarn ad, adresi, ehri, yani hem msteriler hem de saticilar dndrlecek, burada record set'lerin -- birletirilmesi iin UNION kullanlr. SELECT * FROM Satici UNION SELECT * FROM Musteri -- Bu almaz nk dnen record set'lerin kolon saylar ve bu kolonlarn trlerinin ayn olmas gerekir -- Buradaki rnekte aym deildir. SELECT SaticiAd, Adres, SehirNo FROM Satici UNION SELECT MusteriAd, Adres, SehirKod FROM Musteri -- Birletirilen tablolarda ayn data'lar varsa UNION kendisi otomatik olarak DISTINCT uygular. -- UNION'n otomatik olarak DISTINCT uygulamamas iin UNION ALL kullanlr. Bu neden istenir.

-- Briletirilecek tablolar ok bykse ayrca DISTINCT uygulanmas performans etkiler. Bunun iin -- DISTINCT uygulanmas istenmeyebilir. INSERT INTO Satici VALUES('C Dernei', 'Ankara Sok.', 34) SELECT SaticiAd, Adres, SehirNo FROM Satici UNION ALL SELECT MusteriAd, Adres, SehirKod FROM Musteri SELECT SaticiAd, Adres, SehirNo FROM Satici INTERSECT SELECT MusteriAd, Adres, SehirKod FROM Musteri -- Birinci tablodan ikinci tabloda olmayanlar dndrr. Dolaysyla INTERSECT'ler dnmez. SELECT SaticiAd, Adres, SehirNo FROM Satici EXCEPT SELECT MusteriAd, Adres, SehirKod FROM Musteri ALT SORGULAR -- DERIVED (TRETLM) TABLOLAR SELECT StokKod, StokAd FROM (SELECT StokKod, StokAd, Kdv FROM Stok) AS s ----------------------------------------------------------------SELECT CASE WHEN SehirAd IS NULL AND UrunGrupAd IS NULL THEN 'Genel Toplam' WHEN SehirAd IS NULL THEN 'rn Toplam' ELSE SehirAd END, CASE WHEN SehirAd IS NULL AND UrunGrupAd IS NULL THEN '' WHEN UrunGrupAd IS NULL THEN 'Sehir Toplam' ELSE UrunGrupAd END, [Toplam Tutar] FROM (SELECT Sehir.SehirAd, UrunGrup.UrunGrupAd, Sum(Fatura.GenelToplam) AS [Toplam Tutar] FROM FaturaDetay JOIN Fatura ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod JOIN Sehir ON Sehir.SehirNo = Fatura.NakliyeSehir GROUP BY Sehir.SehirAd, UrunGrup.UrunGrupAd WITH CUBE) d -- Birim fiyat en pahal stok: stokkod, stokad, stokfiyat, kdv SELECT Top 3 StokKod, StokAd, StokFiyat, Kdv FROM Stok ORDER BY StokFiyat DESC -- En pahal ilk 5'ten sonra gelen 3 rn getir. SELECT StokKod, StokAd, StokFiyat FROM (

SELECT TOP 3 StokKod, StokAd, StokFiyat, Kdv FROM (SELECT TOP 8 StokKod, StokAd, StokFiyat, Kdv FROM Stok ORDER BY StokFiyat DESC) s ORDER BY StokFiyat ASC ) s ORDER BY StokFiyat DESC

23 Austos 2008 Burada yaplan ilem her bir alt-sorgu iin geici sorgular oluturarak da yaplabilirdi: -- En pahal ilk 5'ten sonraki 3' getiren yukardaki sorgu geici tablolarla aadaki gibi de yaplabilir: SELECT TOP 8 StokKod, StokAd, StokFiyat, Kdv INTO #Ilk8 FROM Stok ORDER BY StokFiyat DESC SELECT TOP 3 StokKod, StokAd, StokFiyat, Kdv INTO #Son3 FROM #Ilk8 ORDER BY StokFiyat ASC -- DROP TABLE #Son3 SELECT StokKod, StokAd, StokFiyat, Kdv FROM #Son3 ORDER BY StokFiyat DESC DROP TABLE #Ilk8 DROP TABLE #Son3 Yukardaki trden bir i mant olan sorguyu SQLServer2005 ile birlikte gelen row_number() fonksiyonu ile yapabiliriz. Takma isimler WHERE clauseunda kullanlamyor. Command Table Expression adnda bir kavram SQL Server 2005 ile dahil olmutur.

-- ctel1 bir tablo olmak zere bu tablo AS'den sonra gelen sorgu ile oluturulur. Geici tabloya gre avantaj tablo -- nesnesi yaratmaya gerek olmamasdr. Alt-sorgunun yerini tutabilir. WITH ctel1 AS (SELECT row_number() OVER (ORDER BY StokFiyat DESC) rowno, * FROM Stok) SELECT * FROM ctel1 WHERE rowno BETWEEN 6 AND 8 -- Artk rowno bir takma ad deil, Command Table Expression kullanlarak rowno gerek bir kolon adna dntrld. Common Table Expression (CTE) ile artk alt-sorgularn bir nesne ad var. Dolaysyla sadece o nesne ad kullanlarak baka yerlerde de kullanlabilir. Eer CTE olmasayd byle bir durumda her defasnda alt-sorgunun tekrar tekrar yazlmas gerekirdi. (CTE sanki o sorgunun geri dnn saklayan bir deiken gibi.)

Alt-sorgularn ilk ekli tretilmi tablolardr. Alt sorgular WHEREde ve kolonlarda kullanlabilir. NOT IN: Bir alt-sorguda elde edilenlerin ierisinde olmayanlar getir:

SELECT StokKod, StokAd, StokFiyat FROM Stok WHERE StokKod NOT IN (SELECT DISTINCT StokKod FROM FaturaDetay)

24 Austos 2008 Getdate() fonksiyonu => O anki zaman getirir. oklu sonu dndren alt-sorgularda karlatrma eittir ile deil IN keyword ile yaplr Karmak sorgular anlamlandrmak iin genelden zele sorgular paralara bl. ie sorgularda dtaki deiken ierdekini grebilir ancak ierideki dardakini gremez. Deyimlerin says birden fazlaysa begin end aral ierisinde yazlmaldr.

if EXISTS(SELECT * FROM sysobjects WHERE id = object_id('Deneme')) BEGIN PRINT 'Tablo var' DROP TABLE Deneme END Bir nesne taral iken alt + F1e baslrsa o nesne hakknda tm veriler dndrlr.

INSERT 1) 2) 3) 4) Insert <Tablo Ad> [Kolon Listesi] VALUES(<Deerler>) Insert <Tablo Ad> [Kolon Listesi] SELECT sorgusu Insert <Tablo Ad> [Kolon Listesi] EXEC MyStoredProc // Scalar Insert <Tablo Ad> [Kolon Listesi] EXEC(<Tablo eklinde veri dndren bir sp>) // Tabular 5) Select <Kolon Listesi> Into <Yeni Tablo Ad> From <Tablo Ad> 6) Insert <Tablo Ad> VALUES(<Deerler>)

-- Yaratlacak tablo nceden varsa onu drop et ve belirttiim yenisini olutur. Bunun iin kullanlan bir kalp var: if EXISTS(SELECT * FROM sysobjects WHERE id = object_id('Deneme')) BEGIN PRINT 'Tablo var' DROP TABLE Deneme END UPDATE 1) Update <Tablo Adi> SET <KolonAd> = <Deer>, <KolonAd> = <Deer>, ... Where <Kosulfadesi>

HARC BR VERTABANI LE LEM YAPMA (AYNI SERVERDAKLERLE)


ServerAd.VeritabanAd.emaAd.NesneAd Ayn serverda isek server ismi yazmak art deil SELECT * FROM <VeritabanAd>.dbo.<TabloAd> Farkl serverda ise: SELECT * FROM <ServerAd>.<VeritabanAd>.<emaAd>.<TabloAd> Ex. SELECT * FROM javax3.Cevahir.dbo.Sehir Eer kar makinadaki ema ad ile bizimki ayn ise ema ad yazmak zorunlu deildir: SELECT * FROM javax3.Cevahir.dbo.Sehir ile SELECT * FROM javax3.Cevahir..Sehir yazmak ayndr. DBde eer birden fazla firmann datasn tutuyorsak, firma adlarn dbde ema ad olarak kullanabiliriz. Kendi makinamda SELECT * FROM Sehir yazmakla SELECT * FROM lambert.hbb.dbo.Sehir yazmak ayndr. SQL Serverda server bir servis olarak alrken Oracleda her bir database bir service olarak alr.

SCRPTLER -- StokKod, StokAd, StokFiyat OrtalamaStokFiyat SELECT StokKod, StokAd, StokFiyat, AVG(StokFiyat) FROM Stok ORDER BY StokFiyat -- HATALI -- Dorusu: Alt-sorgu kolon adlar arasna eklenebilir. SELECT StokKod, StokAd, StokFiyat, (SELECT AVG(StokFiyat) FROM Stok) Stok -- Fatura tablosundan her bir msteriye kesilmi faturalar: faturaNo, musteri, toplam, ortalamas SELECT * FROM Fatura SELECT Fatura.FaturaNo, Fatura.Toplam, Musteri.MusteriAd, ( SELECT AVG(Fatura.Toplam) FROM Fatura) AS [Fatura Toplam Ortalamas] FROM Fatura JOIN Musteri ON Musteri.MusteriNo = Fatura.MusteriNo -- TOP-QUERIES YA DA CORRELATED SUB-QUERIES (likili alt-sorgular) -- Her bir musterinin musteri baznda yapt alm ve kendi ortalamas | GROUP BY istenmiyor FROM

SELECT FaturaNo, MusteriNo, Toplam, (SELECT AVG(Toplam) FROM Fatura ff WHERE f.MusteriNo = ff.MusteriNo) AS [Ortalama Toplam] FROM Fatura AS f -- Alt-sorguda musteri no'lar uyuanlarn AVG(Toplam)'larn alyor. -- alma mekanizmas: nce dardaki sorgu istenen veriyi alt-sorguya geiyor, ardndan alt sorgu ileniyor -- ve alt-sorgu bitince top-sorgu ileniyor.

-- Fatura'dan her bir sat elemannn no'su, fatura tarihi, yapt toplam sat, -- o elemann yapt max(toplam) sat SELECT SatisEleman, convert(varchar, Tarih, 103), Toplam, (SELECT MAX(Toplam) FROM Fatura AS ff WHERE f.SatisEleman = ff.SatisEleman) AS [Maksimum Satis], (SELECT MAX(Toplam) FROM Fatura AS ff WHERE f.SatisEleman = ff.SatisEleman) - Toplam AS [Fark] FROM Fatura AS f ORDER BY f.SatisEleman, Tarih -- Her bir elemann max sat yapt tarih SELECT SatisEleman, convert(varchar, Tarih, 103) AS Tarih, Toplam, (SELECT MAX(Toplam) FROM Fatura AS ff WHERE f.SatisEleman = ff.SatisEleman) AS [Maksimum Satis], (SELECT MAX(Toplam) FROM Fatura AS ff WHERE f.SatisEleman = ff.SatisEleman) - Toplam AS [Fark] FROM Fatura AS f ORDER BY f.SatisEleman, Tarih SELECT DISTINCT SatisEleman, ( SELECT min(convert(varchar, Tarih, 103)) FROM Fatura ff WHERE ff.SatisEleman = f.SatisEleman AND Toplam = (SELECT MAX(Toplam) FROM Fatura AS ff WHERE f.SatisEleman = ff.SatisEleman)) FROM Fatura f -- min(): eer max sattan birden fazla gn yapmsa bir tanesini alr. -- Yukardaki sorguya max sat yapt tarihi de yazdr. SELECT convert(varchar, GetDate(), 103) --------------------------------------------------------------------------SELECT SatisEleman, convert(varchar, Tarih, 103) AS [Satis Tarihi], (SELECT min(convert(varchar, Tarih, 103)) FROM Fatura ff WHERE ff.SatisEleman = f.SatisEleman AND Toplam = (SELECT MAX(Toplam) FROM Fatura fff WHERE fff.SatisEleman = f.SatisEleman)), Toplam,

(SELECT MAX(Toplam) FROM Fatura fff WHERE fff.SatisEleman = f.SatisEleman) AS ElmMaxSatis, Toplam - (SELECT MAX(Toplam) FROM Fatura fff WHERE fff.SatisEleman = f.SatisEleman) AS Fark FROM Fatura f ORDER BY SatisEleman, Tarih ---------------------------------------------------------------------------- 14/08/2008'de sat yapm elemanlarn adn dndr SELECT * FROM Fatura -- 1.Yntem: JOIN ile SELECT DISTINCT Personel.SicilNo, Personel.PersonelAd FROM Fatura JOIN Personel ON Personel.SicilNo = Fatura.SatisEleman WHERE Tarih = '20080824' -- 2.Yntem: Alt-sorgu ile SELECT Personel.PersonelAd FROM Personel WHERE Personel.SicilNo IN (SELECT SatisEleman FROM Fatura WHERE Tarih = '20080824') -- 3.Yntem [ EXISTS() Fonksiyonu ile] SELECT Personel.SicilNo, Personel.PersonelAd FROM Personel WHERE EXISTS(SELECT * FROM Fatura WHERE Fatura.SatisEleman = Personel.SicilNo AND Tarih = '20080824') -- EXISTS() fonksiyonundan true ya da false dner. Yani speisifik bir kolon belirtmenin bir anlam yoktur. -- Yldz konabilir. WHERE clause'unda o tarihte sat yapan elemanlar kontrol edilir. -- Yaratlacak tablo nceden varsa onu drop et ve belirttiim yenisini olutur. -- Bunun iin kullanlan bir kalp var: CREATE TABLE Deneme ( a int ) if EXISTS(SELECT * FROM sysobjects WHERE id = object_id('Deneme')) DROP TABLE Deneme CREATE TABLE Deneme ( x real ) --------------------------------------------------------------------------if EXISTS(SELECT * FROM sysobjects WHERE id = object_id('Deneme')) BEGIN PRINT 'Tablo var' DROP TABLE Deneme END CREATE TABLE Deneme ( x )

real

-- DER DML KOMUTLARI ------------------------------------------------------------------UPDATE Personel SET Adres = 'Bakrky'

UPDATE Musteri SET VergiNo = 'Girilecek', VergiDairesi = 'Girilecek' WHERE VergiNo IS NULL AND VergiDairesi IS NULL -- Marmara Blgesi'ndeki mterilerin bakiyelerini %10 artr. UPDATE Musteri SET Bakiye = Bakiye * 1.10 FROM Musteri JOIN Sehir ON Sehir.SehirKod = Musteri.SehirKod JOIN Bolge ON Bolge.BolgeNo = Sehir.BolgeNo WHERE Bolge.BolgeAd LIKE '%Marmara%' -- HARC BR VERTABANI LE LEM YAPMA (Ayn server'dakilerle) SELECT * FROM lambert.hbb.dbo.Sehir BAKA BR SERVERA BALANMA Baka bir servera erieceksek nce bu server SQL Servera tantmamz gerekir. Object Explorer > Security > Loginste kullanclar tanmldr. Ayn serverdaki baka bir dbye erimek iin bu kullancalara buradan yetki verebilirim. Ancak baka bir servern loginsi nasl bilmiyoruz. Dolaysyla nce uzaktaki servern buraya tantlmas gerekir. Object Explorer > Server Objects > Linked Server > New... = Linked Servera makina ad yaz. Security ksmnda kar servera balanrken kardaki hangi kullancnn yetkileri ile balanacam seeceim. (Karda benim iin bir kullanc yaratrlar) En altta be made using the....dan kar makinadaki kullancy tanmla.

30 Austos 2008

PROGRAMLAMA NESNELER
VIEW'LER
View'ler: Kaydedilmi SQL sorgulardr. Bir view yle yazlr:

CREATE VIEW vw_IstanbulMusterileri AS SELECT * FROM Musteri WHERE SehirKod = 34 Artk, bu view'i tablo kullanlan her yerde kullanabiliriz. View, kaydedilmi sql sorgulardr. View'ler kalcdr. DB'ye eklenirler. Adeta sanal bir tablodur. View'de bir maniplasyon ilemi yapldnda bu maniplasyon asl tabloya da yansr. Her defasnda karmak sorgular yapmak yerine elde edilen bu karmak tablo bir view'de saklanabilir. Geici tablolar sorgu sonucunda yok edilir ve bellekte yer kaplarlar. View'ler kalcdr ve bellekte deil DB'de saklanrlar. SELECT INTO ile yaratlan tablolar birer formasyonunu deitirir. View'den fark budur. gerek tablodur. DB'nin tablo

Yetkilendirme yaparken rnein admin bir alt-yetkidekinin musteriler tablosundan sadece Istanbul'daki msterileri grmesini isteyebilir. te burada view kullanlr. Yani view'ler karmak sorgularda ie yarad gibi yetkilendirmede de ie yarar.

Kolon baznda yetkilendirme CREATE VIEW vw_SehirUrunToplamSatis AS SELECT Sehir.SehirAd, UrunGrup.UrunGrupAd, Sum(Fatura.GenelToplam) AS GenelToplam FROM FaturaDetay JOIN Fatura ON FaturaDetay.FaturaNo = Fatura.FaturaNo JOIN StokUrunGrup ON FaturaDetay.StokKod = StokUrunGrup.StokKod JOIN UrunGrup ON StokUrunGrup.UrunGrup = UrunGrup.UrunGrupKod JOIN Sehir ON Sehir.SehirKod = Fatura.NakliyeSehir GROUP BY Sehir.SehirAd, UrunGrup.UrunGrupAd SELECT SehirAd, GenelToplam FROM vw_SehirUrunToplamSatis ------------------------------------------------------ Kolonlara gre yetkilendirme. rnein Personel tablosundaki Maas kolonunun tm kullanclar tarafndan -- grlmesini istemiyoruz. Peki, o kolonu saklamak iin ne yapabiliriz ? Bir view yaratrz ve bu view -- Personel tablosundaki Maas kolonu haricindeki tm kolonlardan oluur. CREATE VIEW vw_Personel AS SELECT SicilNo, PersonelAd, Adres, Sehir, Bolum, BagliOlduguKisi FROM Personel SELECT * FROM vw_Personel ---------------------------------------------------- View'in sonucundan tek tablo etkileniyorsa insert, update, delete yapabiliriz ancak view birden fazla tablo ile oluturulmusa (join'lenerek) bu maniplasyon ilemleri yaplamaz. INSERT yaparken grnmn kapsamad tablolardaki stunlarn NULL alma yeteneinin olmas gerekir. VIEW ierisinde ORDER BY saf olarak kullanlamaz ancak TOP kullanlan bir sorguda ORDER BY kullanlabilir.

-- Bolge - Sehir baznda mteriler => BolgeAd, SehirAd, MusteriNo, MusteriAd, Bakiye CREATE VIEW vw_BolgeSehirBazindaMusteri AS SELECT Bolge.BolgeAd, Sehir.SehirAd, Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri JOIN Sehir ON Sehir.SehirKod = Musteri.SehirKod JOIN Bolge ON Bolge.BolgeNo = Sehir.BolgeNo SELECT * FROM vw_BolgeSehirBazindaMusteri VIEW'lerde saklanan tek ey sorgunun kendisi deildir aslnda. View'lerin kendisi de indekslenebilir. Bu konuya derste deinilmeyecek. Ad materialized view denir.

STORED PROCEDURES

SP'ler kendi bana alabilen kod paralardr. Birtakm parametreler alabilir, output parametreleri ve result set dndrebilir. Bir SP birden fazla result set'i dndrebilir ve alma sonucunu dndrr.

-- STORED PROCEDURES CREATE PROC up_BolgeSehirMusteriGetir AS SELECT Bolge.BolgeAd, Sehir.SehirAd, Musteri.MusteriNo, Musteri.MusteriAd, Musteri.Bakiye FROM Musteri JOIN Sehir ON Sehir.SehirKod = Musteri.SehirKod JOIN Bolge ON Bolge.BolgeNo = Sehir.BolgeNo --Stored procedure' altrmak iin: EXEC up_BolgeSehirMusteriGetir SP'nin avantajlar: Daha yapsaldr ve hataya kar direnlidir. Stored procedure'ler normal sorgulara gre daha hzl alr. SP'ler daha az network trafii olutururlar. Bir kere yazlp bir ok yerden arlabilirler. Alttaki yapy yani kendi implementasyonunu kullananlardan gizler. Neden daha yapsaldr ? Ortada. Neden daha hzldr ? Bir sorgu altrlnca SQL Server birtakm ilemler yapar: parse eder, sentaks doru mu kontrol eder, sonra hangi indeks ve tabloyu kullanarak sorguyu yapacak db engine bunlar sras ile yapar (buna altrma plan denir). SP'lerde ise bu ilemler bir kere yaplr ve sonradan bu ilemler tekrar tekrar yaplmaz, varolan Execution Plan' kullanr. (Bu ileme derleme denir.) Management Studio'da menu'den Query > Include Execution Plan ile alma plan grntlenebilir. Execution Plan'i Query Optimizer oluturur ve DB Engine buna gre davranr.

Neden daha az network trafii oluturur ? Bir sayfa sorgu yollayacama tek satr SP gnderip ilemi gerekletirebiliriz. SP iinde SP arlabilir hatta zyinelemeli bir yap da oluturulabilir.

-- Pseudo procedure CREATE PROC up_SatisEkle AS BEGIN TRANSACTION BEGIN TRY EXEC up_FaturaEkle EXEC up_FaturaDetayEkle EXEC up_StokMiktarDegistir EXEC up_MusteriBakiyeDegistir COMMIT TRAN END TRY BEGIN CATCH ROLLBACK TRAN END CATCH END

BEGIN TRAN ile balayp COMMIT etmedike o tablo kilitlenir. (LOCK) SP_LOCK prosedr o anda kilitli olanlar getirir. Kilitli olmasna ramen tabloyu grmek istersek (dirty read - kirli okuma => veri son-net haline daha erimemi) aadaki gibi bir script kullanabiliriz:

SELECT * FROM Sehir(NOLOCK) -- O anda Sehir tablosu bir transaction ierisinde yer alyorsa ve henz COMMIT yaplmamsa Sehir tablosu LOCK durumundadr. LOCK durumunda bir tabloyu NOLOCK komutu ile grntleyebiliriz. Gelen veriyi Kirli okuma (dirty read) ile okur. Transaction BEGIN TRAN ile balar. ROLLBACK yaparken eski bilgi transaction log'da saklanr ve oradan yenilenir. Ancak truncate ettiysek log sfrlanaca iin ROLLBACK yapamaz.

SELECT @@TRANCOUNT -- Aktif olan transaction saysn getirir. ie script'lerin olduu bir yapda ierdekilerden birinde ROLLBACK oluursa da doru hepsi ROLLBACK olacaktr. Ancak ierdekilerden biri COMMIT olursa sadece o COMMIT olmu olur. Bir transaction ve exception handling rnei:

BEGIN TRAN BEGIN TRY EXEC up_SehirEkle 34, 'New York', 5 EXEC up_SehirEkle 76, 'New Jersey', 5 COMMIT END TRY BEGIN CATCH PRINT 'An error occured!..' ROLLBACK TRAN END CATCH

Exception Handling'in olmad zamanlarda (SQL Server 2005 ncesi) bu ilem aadaki gibi yaplrd:

BEGIN TRAN EXEC up_SehirEkle 34, 'New York', 5 IF @@error != 0 GOTO HATA EXEC up_SehirEkle 76, 'New Jersey', 5 IF @@error != 0 GOTO HATA COMMIT HATA: PRINT 'An error occured!..' ROLLBACK TRAN 31 Austos 2008

View'ler ile satr ve kolon baznda yetkilendirme yaplabiliyor. (Detay iin bak. nceki ders notlar) Bir sayfa sorgu yollayacama tek satr SP gnderip ilemi gerekletirebiliriz.

TRANSACTION RNEKLER: BEGIN TRAN BEGIN TRY UPDATE ABank.dbo.Hesap SET Bakiye = Bakiye - 10000 WHERE MusteriNo = 1 UPDATE Musteri SET Bakiye = Bakiye + 10000 WHERE MusteriNo = 1 COMMIT END TRY BEGIN CATCH PRINT 'Transaction basarisiz oldu!..' ROLLBACK TRAN END CATCH PRINT 'Islem basari ile tamamlandi!..'

CREATE PROC up_MusteriOdemeYap @musteriNo int, @tutar decimal(18 ,2) AS BEGIN IF @tutar < 0 GOTO HATA

IF NOT EXISTS(SELECT * FROM ABank.dbo.Hesap WHERE MusteriNo = @musteriNo) GOTO HATA IF NOT EXISTS(SELECT * FROM Musteri WHERE MusteriNo = @musteriNo) GOTO HATA BEGIN TRAN BEGIN TRY UPDATE ABank.dbo.Hesap SET Bakiye = Bakiye - @tutar WHERE MusteriNo = @musteriNo UPDATE Musteri SET Bakiye = Bakiye + @tutar WHERE MusteriNo = @musteriNo COMMIT TRAN END TRY BEGIN CATCH

PRINT 'Transaction basarisiz oldu!..' ROLLBACK TRAN END CATCH PRINT 'Islem basari ile tamamlandi!..' HATA: END PRINT 'lem geersiz!..'

EXEC up_MusteriOdemeYap 4, 9876 Database'de oluan DB hatalar Books Online'dan "Database Engine Error Severities" diyerek ulalabilir. Bu hata mesajlar kullanc hata mesajlar ya da sistemin bize verdii mesajlar olarak gruplara ayrlr. RAISERROR() fonksiyonu ikinci parametre olarak bir DB Engine Error numaras alr. Genellikle 16'y argman olarak geer,z Kendimiz bir mesaj tanmlayabiliriz. msg_id ya da msg_string verebiliriz. 0-50000 aras SQL Server'n kulland hata numaralardr. sp_addmessage sp'si ile kendimiz hata mesaj tanmlayabiliriz. Hata numaras olarak 50001'den itibaren bir say vermemiz gerekir. Bir hata mesajn aadaki gibi oluturup DB'ye ekleyebiliriz: EXEC sp_addmessage 50001, 16, N'Toplam veya KDV hatal' RAISERROR(50001, 16, 1) sp_altermessage sp_dropmessage sp'leri ile mesajlar zerinde maniplasyon ilemleri yaplabilir. Eklenmi olan message'ler sys.sysmessages view'inden grntlebilir. SELECT * FROM sys.sysmessages WHERE error > 50000 -- Kendi hata mesajlarmz grntlemek iin kullanlr. Bir stored prosedrden geri dn deeri almak iin (burada output parameter deniyor) nce aadaki gibi bir deiken tanmlamak gerekir: @faturaNo int OUTPUT

TRY ierisinde @faturaNo deikenine atama yaplr. SP dardan arlrken bir deiken tanmlanr ve aadaki gibi bir sentaks kullanlr. DECLARE @retVal int EXEC up_FaturaKes 1, '20080831', 3000, 18, 1, 34, @retVal out SELECT @retVal OUTPUT parametresini ieren stored procedure'n implementasyonu aadaki gibidir:
ALTER PROC up_FaturaKes @musteriNo int, @tarih datetime,

@toplam decimal(10,2), @kdv int, @satisEleman int, @nakliyeSehir int, @faturaNo int OUTPUT AS BEGIN

-- OUTPUT bu deikenin bir output parametresi olduunu gsterir

IF NOT EXISTS(SELECT * FROM Musteri WHERE MusteriNo = 1) BEGIN RAISERROR('Musteri yok', 16, 1) RETURN END IF NOT EXISTS(SELECT * FROM Personel WHERE SicilNo = @satisEleman) BEGIN RAISERROR('Musteri yok', 16, 1) RETURN END IF NOT EXISTS(SELECT * FROM Sehir WHERE Sehir.SehirKod = @nakliyeSehir) BEGIN RAISERROR('Sehir yok', 16, 1) RETURN END IF @toplam <= 0 OR @kdv <= 0 BEGIN RAISERROR(50001, 16, 1) -- 50001 hata mesaj biraz aada benim tarafmdan tanmland. RETURN END BEGIN TRAN BEGIN TRY INSERT INTO Fatura(MusteriNo, Tarih, Toplam, Kdv, SatisEleman, NakliyeSehir) VALUES(@musteriNo, @tarih, @toplam, @toplam * .18, @satisEleman, @nakliyeSehir) SELECT @faturaNo = @@IDENTITY UPDATE Musteri SET Bakiye = Bakiye - (@toplam * 18) COMMIT TRAN END TRY BEGIN CATCH PRINT 'Bir exception olutu' ROLLBACK TRAN END CATCH END

Zam yapan ve zaam alan kii saysn dndren SP aadaki gibi yazlabilir:

CREATE PROC up_BolumeGorePersonelZamVeZamAlansayisi @bolumNo int, @zamOrani decimal(10, 2), @zamliKisiSayisi int OUTPUT AS BEGIN IF NOT EXISTS(SELECT * FROM Personel WHERE Bolum = @bolumNo) BEGIN

RAISERROR('Blm yok', 16, 1) RETURN END IF @zamOrani = 0 BEGIN RAISERROR('Hatal zam oran girdiniz', 16, 1) RETURN END BEGIN TRAN BEGIN TRY UPDATE Personel SET Maas = Maas * (100 + @zamOrani) / 100 WHERE Bolum = @bolumNo SELECT @zamliKisiSayisi = COUNT(*) FROM Personel WHERE Bolum = @bolumNo COMMIT END TRY BEGIN CATCH PRINT 'Bir exception olutu!..' ROLLBACK TRAN END CATCH END DECLARE @retVal int EXEC up_BolumeGorePersonelZamVeZamAlansayisi 1, 10, @retVal out SELECT @retVal

-- Zam yapan ve zamdan yararlanan ve yararlanmayan saysn dndren SP


ALTER PROC up_BolumeGorePersonelZamVeZamAlansayisi @bolumNo int, @zamOrani decimal(10, 2), @zamliKisiSayisi int OUTPUT, @zamsizKisiSayisi int OUTPUT AS BEGIN IF NOT EXISTS(SELECT * FROM Personel WHERE Bolum = @bolumNo) BEGIN RAISERROR('Blm yok', 16, 1) RETURN END IF @zamOrani = 0 BEGIN RAISERROR('Hatal zam oran girdiniz', 16, 1) RETURN END BEGIN TRAN BEGIN TRY UPDATE Personel SET Maas = Maas * (100 + @zamOrani) / 100 WHERE Bolum = @bolumNo SELECT @zamliKisiSayisi = COUNT(*) FROM Personel WHERE Bolum = @bolumNo SELECT @zamsizKisiSayisi = COUNT(*) FROM Personel WHERE Bolum != @bolumNo COMMIT END TRY

BEGIN CATCH PRINT 'Bir exception olutu!..' ROLLBACK TRAN END CATCH END DECLARE @zamAlanSayisi int DECLARE @zamAlmayanSayisi int EXEC up_BolumeGorePersonelZamVeZamAlansayisi 1, 10, @zamAlanSayisi OUT, @zamAlmayanSayisi OUT SELECT cast(@zamAlanSayisi AS varchar) AS [Zam alan personel says], cast(@zamAlmayanSayisi AS varchar) AS [Zam almayan personel says]

-- Alternatif SP arma biimi: DECLARE @zamAlanSayisi int DECLARE @zamAlmayanSayisi int EXEC up_BolumeGorePersonelZamVeZamAlansayisi @zamOrani = 10, @bolumNo = 1, @zamliKisiSayisi = @zamAlanSayisi OUT, @zamsizKisiSayisi = @zamAlmayanSayisi OUT Output parametresi default deer alabilir ve sp arlrken artk bu parametre yer almaz ancak artk sp'yi arrken alternatif ar biiminde armamz gerekir:

-- BolumNo'su hi verilmez ya da sfr geilirse herkese zam yaplsn -- PARAMETRELERE DEFAULT DEER VERLEBLR
ALTER PROC up_BolumeGorePersonelZamVeZamAlansayisiDefaultDegerli @bolumNo int = 0, -- DEFAULT DEER ALDI @zamOrani decimal(10, 2), @zamliKisiSayisi int OUTPUT, @zamsizKisiSayisi int OUTPUT AS BEGIN IF @zamOrani = 0 BEGIN RAISERROR('Hatal zam oran girdiniz', 16, 1) RETURN END BEGIN TRAN BEGIN TRY IF (@bolumNo = 0) BEGIN UPDATE Personel SET Maas = Maas * (100 + @zamOrani) / 100 SELECT @zamliKisiSayisi = COUNT(*) FROM Personel SELECT @zamsizKisiSayisi = 0 END ELSE BEGIN UPDATE Personel SET Maas = Maas * (100 + @zamOrani) / 100 WHERE Bolum = @bolumNo SELECT @zamliKisiSayisi = COUNT(*) FROM Personel WHERE Bolum = @bolumNo SELECT @zamsizKisiSayisi = COUNT(*) FROM Personel WHERE Bolum != @bolumNo END

COMMIT END TRY

BEGIN CATCH PRINT 'Bir exception olutu!..' ROLLBACK TRAN END CATCH END DECLARE @zamAlanSayisi int DECLARE @zamAlmayanSayisi int EXEC up_BolumeGorePersonelZamVeZamAlansayisiDefaultDegerli @zamOrani = 10, @zamliKisiSayisi = @zamAlanSayisi OUT, @zamsizKisiSayisi = @zamAlmayanSayisi OUT SELECT @zamAlanSayisi AS [Zam alan personel says], @zamAlmayanSayisi AS [Zam almayan personel says]

6 Eyll 2008 CURSOR'LAR Cursor'ler her bir satr zerinde ilerlemeyi salyor. Bir cursor verinin kendisini ADO.NET'teki DataReader'n tuttuu gibi tutar ve satr satr ilerlememizi salar.

DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici -- cursor'n iine yklenen data OPEN c -- Yukarda cursor sadece tanmland. Kullanlmas iin OPEN ile almas gerekir. FETCH NEXT FROM c -- FETCH her defasnda sras gelen satrn tamamn alr. WHILE (@@fetch_status = 0) -- fetch_status eer sfr ise bu halen cursor'un sonuna gelinmediini gsterir. BEGIN FETCH NEXT FROM c END CLOSE c -- Bu referans invalid hale getirir. DEALLOCATE c -- cursor nesnesini yok eder.

fetch_status, eer cursor'de sona gelinmise -1 dndrr.

Stok kontrol yapan cursor nesnesi kullanlm stored prosedr:


DECLARE @saticiNo int DECLARE @saticiAd varchar(50) DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici OPEN c FETCH NEXT FROM c INTO @saticiNo, @saticiAd -- Satrdaki bilgiler deikenlere atanr. WHILE (@@fetch_status = 0) BEGIN EXEC ('SELECT StokKod, StokAd, MaxStok - Miktar AS Adet INTO AlimSiparis' + @saticiAd + 'FROM Stok WHERE Miktar < MinStok AND Satici = ' + @saticiNo) FETCH NEXT FROM c INTO @saticiNo, @saticiAd END CLOSE c DEALLOCATE c

-- Dinamik olarak DROP TABLE kullanld.


DECLARE @saticiNo int DECLARE @saticiAd varchar(50) DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici OPEN c FETCH NEXT FROM c INTO @saticiNo, @saticiAd -- Satrdaki bilgiler deikenlere atanr. WHILE (@@fetch_status = 0) BEGIN EXEC ('DROP TABLE AlimSiparis' + @saticiAd) EXEC ('SELECT StokKod, StokAd, MaxStok - Miktar AS Adet INTO AlimSiparis' + @saticiAd + 'FROM Stok WHERE Miktar < MinStok AND Satici = ' + @saticiNo) FETCH NEXT FROM c INTO @saticiNo, @saticiAd END CLOSE c DEALLOCATE c

Deminki prosedrn iyiletirilmi hali:


ALTER PROC up_AlimSiparisOlustur AS BEGIN DECLARE @saticiNo int DECLARE @saticiAd varchar(50) DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici OPEN c FETCH NEXT FROM c INTO @saticiNo, @saticiAd WHILE (@@fetch_status = 0) BEGIN EXEC ('DROP TABLE AlimSiparis' + @saticiAd) EXEC ('SELECT StokKod, StokAd, MaxStok - Miktar AS Adet INTO AlimSiparis' + @saticiAd + 'FROM Stok WHERE Miktar < MinStok AND Satici = ' + @saticiNo) FETCH NEXT FROM c INTO @saticiNo, @saticiAd END CLOSE c DEALLOCATE c END

Dinamik, Scrollable gibi baka CURSOR eitleri bulunmaktadr.

Yukardaki SP'nin bir job olarak bir schedule'e balanp altrlmasn istiyorsak bunu SQL Agent'ten yapmak gerekir. Bunun iin SQL Server Configuration Manager'da ya da Ynetimsel Aralar'dan Services'a girerek SQLServerAgent servisinin balatlmas gerekir. Bundan sonra;

Object Explorer'dan Jobs'a sa tkla > new job > Greve sim gir> Sonra steps tab'na ge. Bir grev birden fazla admdan oluabilir. Steps tab'nda Type=T-SQL script se, db'yi se > command'a EXEC <sp ad> yaz ve olutur. Bir job bir scheduler'a balanmak zorunda deildir. Elle de altrlabilir. Sonra Eklenen Job'a Object Explorer'dan sa tkla ve run de. Br job'u iin bir schedule oluturmak iin oluturulmu ilgili job'un zerine object explorer'dan sa tklanarak properties'e girilir ve oradan schedules seilir. new schedule denerek bu job bir schedule'e balanr. Yeni bir step ekliyoruz: Ad ErrorLogla. Burada Command ksmna INSERT ErrorLog VALUES(getdate(), 'hata mesaj') yaz. Sonra birinci step'e git. ve jobs properties'ten advanced'e git ve baar ve baarszlk durumlarndaki davranlar tanmla. Job > View History ile o job'un log'una baklabilir. Bir prosedre object explorer'da listelendii yerden de sa tklanp altrlabilir. stored

mantklarn stored procedure'lere gmp kod ierisinden bu procedure'lerin kullanlmas kurumsal ortamda sklkla tercih ediliyor.

TRIGGER'LAR
Trigger'lar tablo baznda tutulan ve tabloda yaplan belirli ilemlere gre tetiklenen bir kod parasdr. Stok tablosunda bir stok silindiinde bununla ilgili bir trigger'n tetiklenmesini isteyebiliriz. Trigger'lara rnek: Merkezdeki db'de bir deiiklik olduunda git ubelerde de deitir. Bir trigger olutuktan sonra koul olarak o trigger'a gre davranan davranlar oluturulabilir. Musteri Bakiyesi sfr ya da sfrdan kkse bir trigger kullanarak fatura kesmeyi (fatura tablosuna insert edilmesini) engelleyebiliriz.

suser_sname() => u anda server' kullanan kullancnn adn dndrr. Bir trigger rnei: CREATE TRIGGER tr_SehirSil ON Sehir FOR DELETE AS BEGIN INSERT DeletionLog VALUES(getdate(), suser_sname(), 'Sehir') END

MSSQL Server'da bir trigger ierisinde o anda silinen satrlar Deleted adnda zel bir tabloya eklenirler, ayn ekilde eklenen kaytlar Inserted tablosuna, gncellenen kaytlar da Updated tablosuna eklenirler. Bir trigger'n ierisindeyken implicit olarak BEGIN TRAN iinde kod yazarz. Dolaysyla, bir trigger ierisinde kendimiz BEGIN TRAN diye bildirmesek dahi COMMIT ve ROLLBACK yapabiliriz.

CREATE TRIGGER tr_FaturaEklendiBakiyeDusuldu ON Fatura FOR INSERT AS BEGIN DECLARE @faturaTutar decimal(8,2), @musteri int SELECT @musteri = MusteriNo, @faturaTutar = Toplam + Kdv FROM INSERTED DECLARE @bakiye decimal(8,2) SELECT @bakiye = bakiye FROM Musteri WHERE MusteriNo = @musteri if (@bakiye - @faturaTutar) < 0 ROLLBACK -- Buradaki ROLLBACK Musterinin bakiyesini negatif yapacak bir kayt eklenmek istediinde hata verdirecektir. else UPDATE Musteri SET Bakiye = Bakiye - @faturaTutar WHERE MusteriNo = @musteri END

Bir trigger disable edilebilir:

ALTER TABLE Fatura DISABLE TRIGGER tr_FaturaEklendiBakiyeDusuldu

Disable edilen bir trigger ENABLE TRIGGER ile yeniden aktif hale getirilebilir.

USE hbb

Gnn script'leri:

-- MinStok'un altnda kalan stoklar maxstok'a tamamla. ALTER PROC up_AlimSiparisOlustur AS BEGIN DROP DROP DROP DROP TABLE TABLE TABLE TABLE AlimSiparisIndex AlimSiparisKarma AlimSiparisArena AlimSiparisKoyuncu

SELECT StokKod, StokAd, MaxStok - Miktar AS Adet INTO AlimSiparisIndex FROM Stok WHERE Miktar < MinStok AND Satici = 1 SELECT StokKod, StokAd, MaxStok - Miktar AS Adet INTO AlimSiparisKarma FROM Stok WHERE Miktar < MinStok AND Satici = 2

SELECT StokKod, StokAd, MaxStok - Miktar AS Adet INTO AlimSiparisArena FROM Stok WHERE Miktar < MinStok AND Satici = 3 END EXEC up_AlimSiparisOlustur ----------------------------------------------------------------------------SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici ----------------------------------------------------------------------------DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici -- cursor'n iine yklenen data OPEN c -- Yukarda cursor sadece tanmland. Kullanlmas iin OPEN ile almas gerekir. FETCH NEXT FROM c -- FETCH her defasnda sras gelen satrn tamamn alr. -- Dngnn dnda bir defa FETCH NEXT yaplr. Bylece @@fetch_status'e ilkdeer atanm olur. WHILE (@@fetch_status = 0) -- fetch_status eer sfr ise bu halen cursor'un sonuna gelinmediini gsterir. BEGIN -- SELECT @@fetch_status FETCH NEXT FROM c END CLOSE c -- cursor' kapatr. Ancak, cursor nesnesinin tanm halen hayattadr. DEALLOCATE c -- cursor nesnesini yok eder. -----------------------------------------------------------------------------

DECLARE @saticiNo int DECLARE @saticiAd varchar(50) DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici OPEN c FETCH NEXT FROM c INTO @saticiNo, @saticiAd -- Satrdaki bilgiler deikenlere atanr. WHILE (@@fetch_status = 0) BEGIN -- PRINT @saticiAd FETCH NEXT FROM c INTO @saticiNo, @saticiAd END CLOSE c DEALLOCATE c ----------------------------------------------------------------------------ALTER PROC up_AlimSiparisOlustur AS BEGIN DECLARE @saticiNo int DECLARE @saticiAd varchar(50) DECLARE c CURSOR FOR SELECT SaticiNo, substring(SaticiAd, 1, charindex(' ', SaticiAd)) FROM Satici OPEN c FETCH NEXT FROM c INTO @saticiNo, @saticiAd -- Satrdaki bilgiler deikenlere atanr. WHILE (@@fetch_status = 0) BEGIN EXEC ('DROP TABLE AlimSiparis' + @saticiAd) EXEC ('SELECT StokKod, StokAd, MaxStok - Miktar AS Adet

INTO AlimSiparis' + @saticiAd + 'FROM Stok WHERE Miktar < MinStok AND Satici = ' + @saticiNo) FETCH NEXT FROM c INTO @saticiNo, @saticiAd END CLOSE c DEALLOCATE c END ----------------------------------------------------------------------------SELECT SELECT SELECT SELECT * * * * FROM FROM FROM FROM AlimSiparisArena AlimSiparisIndex AlimSiparisKarma AlimSiparisKoyuncu

----------------------------------------------------------------------------CREATE TABLE ErrorLog ( ErrorLogId PRIMARY KEY, Date JobName )

int datetime, varchar(100)

IDENTITY(1,1)

NOT NULL

CREATE TABLE DeletionLog ( DeletionLogId PRIMARY KEY, Date UserName )

int datetime, varchar(100)

IDENTITY(1,1)

NOT NULL

----------------------------------------------------------------------------SELECT suser_sname() ----------------------------------------------------------------------------ALTER TRIGGER tr_SehirSil ON Sehir FOR DELETE AS BEGIN DECLARE @sehirAd varchar(100) SELECT @sehirAd = SehirAd FROM DELETED INSERT DeletionLog VALUES(getdate(), suser_sname(), 'Sehir', @sehirAd) END ----------------------------------------------------------------------------CREATE TRIGGER tr_SehirEkle ON Sehir FOR INSERT AS BEGIN DECLARE @sehirAd varchar(100) SELECT @sehirAd = SehirAd FROM INSERTED INSERT InsertionCityLog VALUES(getdate(), suser_sname(), 'Sehir', @sehirAd) END -- Fatura kesilince musterinin bakiyesi sfrn altna dmemeli [rollback ile geri alnacak]. -- eer derse bir trigger tetikle. CREATE TRIGGER tr_FaturaEklendiBakiyeDusuldu ON Fatura FOR INSERT

AS BEGIN DECLARE @faturaTutar decimal(8,2), @musteri int SELECT @musteri = MusteriNo, @faturaTutar = Toplam + Kdv FROM INSERTED DECLARE @bakiye decimal(8,2) SELECT @bakiye = bakiye FROM Musteri WHERE MusteriNo = @musteri if (@bakiye - @faturaTutar) < 0 ROLLBACK -- Buradaki ROLLBACK Musterinin bakiyesini negatif yapacak bir kayt eklenmek istediinde hata verdirecektir. else UPDATE Musteri SET Bakiye = Bakiye - @faturaTutar WHERE MusteriNo = @musteri END ------------------------------------------------------------------------------ TRIGGER'lar aadaki gibi disable edilebilir: ALTER TABLE Fatura DISABLE TRIGGER tr_FaturaEklendiBakiyeDusuldu

7 Eyll 2008 Ayn i iin birden ok trigger olursa hepsi alrlar. Dolaysyla kullandklar data'ya birden ok trigger erieceinden bu data zerinde birtakm dzensizlikler oluabilir. Bu konuya dikkat edilmelidir. Ayn i iin genelde tm ilemler tek bir trigger ierisinde yaplr. INSTEAD OF trigger' ve FOR (AFTER) trigger' olmak zere trigger'lar ikiye ayrlr. AFTER trigger'nda nce komut alr ve sonra trigger tetiklenir. INSTEAD OF'ta ise trigger' tetikleyen komut almaz, onun yerine INSTEAD OF trigger' alr. TRIGGER ierisindeki ROLLBACK trigger'n sonlanmasna sebep olmaz. Ak ROLLBACK'ten sonra devam eder. Sadece INSERTED ve DELETED tablolar var, bir Updated tablosu yok. UPDATE ilemi gerekletirildiinde update edilen kaydn eski hale Deleted'a eklenir, yeni hali ise Inserted'a eklenir.

ALTER TRIGGER tr_FaturaEklendiBakiyeDusuldu ON Fatura FOR INSERT AS BEGIN DECLARE @faturaTutar decimal(8,2), @musteri int SELECT @musteri = MusteriNo, @faturaTutar = Toplam + Kdv FROM INSERTED DECLARE @bakiye decimal(8,2) SELECT @bakiye = bakiye FROM Musteri WHERE MusteriNo = @musteri if (@bakiye - @faturaTutar) < 0 BEGIN RAISERROR('Bakiye yetersiz', 16, 1) ROLLBACK -- RETURN

else

END

PRINT 'ROLLBACK''ten sonra ama hala begin-end aralnda'

UPDATE Musteri SET Bakiye = Bakiye - @faturaTutar WHERE MusteriNo = @musteri

END

PRINT 'ROLLBACK''ten sonra'

INSERT Fatura VALUES(1, GetDate(), 1000, 180, -- INSERT, DELETE, UPDATE iin ayn anda tek satr zerinde ilem yaplsn. -- Mesela tm satrlar bir kerede maniple etmek mmkn olmasn. -- 1) row_count ile yaplr. 2) INSERTED gibi tablolardan COUNT dndrlr.
ALTER TRIGGER tr_TekSatirliIslemKisitiKondu ON Fatura AFTER INSERT, UPDATE, DELETE AS BEGIN if ((SELECT COUNT(*) FROM Deleted) > 1 OR (SELECT COUNT(*) FROM Inserted) > 1) BEGIN RAISERROR('HATA: Ayn anda yalnzca tek bir satir zerinde ilem yaplabilir.', 16, 1) ROLLBACK TRAN RETURN END ELSE BEGIN COMMIT END END BEGIN TRAN DELETE Fatura

Inserted ve Deleted tablolar read-only'dir.

-- Yeni bir musteri eklendiinde o musteriye bir hesap kodu verilmeli. Hesap kod rn: 100.01.00001 -- Her yeni musteri eklendiinde nceki numaradan bir sonrakini yeni musteriye hesap kodu olarak ekle. ALTER TRIGGER tr_MusteriHesapKodEkle ON Musteri AFTER INSERT AS BEGIN DECLARE @yeniNo varchar(20), @musteriNo int SELECT @yeniNo = RIGHT(('0000' + cast(max(cast(right(MuhasebeHesapKod, 5) AS int)) + 1 AS varchar)), 5) FROM Musteri SELECT @musteriNo = MusteriNo FROM Inserted UPDATE Musteri SET MuhasebeHesapKod = '100.01.' + @yeniNo WHERE MusteriNo = @musteriNo END Bu sorgunun bir eksii var. MAX no'ya sahip kayt silinirse fakat o no baka tablolarda kullanlmsa ve bir sonraki kayt ayn MAx No'yu alrsa dier tablolar iin iki mteri ayn

hesap no'yu gsteriyor olacak. Bunu dzeltmek iin genelde yardmc kalc bir tablo kullanlr:
ALTER TRIGGER tr_MusteriHesapKodEkle ON Musteri AFTER INSERT AS BEGIN DECLARE @yeniNo varchar(20), @musteriNo int SELECT @yeniNo = RIGHT(('0000' + cast(cast(right(SeriNo, 5) AS int) + 1 AS varchar)), 5) FROM Seri WHERE SeriAd = 'MusteriHesapKod' SET @yeniNo = '100.01.' + @yeniNo SELECT @musteriNo = MusteriNo FROM Inserted UPDATE Musteri SET MuhasebeHesapKod = @yeniNo WHERE MusteriNo = @musteriNo UPDATE Seri SET SeriNo = @yeniNo WHERE SeriAd = 'MusteriHesapKod' END

-- Musteri silinmek istediinde musteriyi silmeyecek, bir log tablosuna u kullanc u musteri kaydn -- silmek istedi diye yazlacak CREATE TRIGGER tr_MusteriSilmekIsteyeniRaporEt ON Musteri INSTEAD OF DELETE AS BEGIN INSERT INTO Rapor VALUES(cast(suser_sname() AS varchar), 'Musteri', getdate()) END

Silinmek istenen mteri adn da raporlar:


ALTER TRIGGER tr_MusteriSilmekIsteyeniRaporEt ON Musteri INSTEAD OF DELETE AS BEGIN DECLARE @musteriAd varchar(100) SELECT @musteriAd = MusteriAd FROM Deleted INSERT INTO Rapor VALUES(cast(suser_sname() AS varchar), 'Musteri', getdate(), @musteriAd) END

INSTEAD OF tanmlanamaz.

trigger'lar

VIEW'lerde

tanmlanabilir.

Dier

trigger

eidi

FUNCTIONS
Fonksiyon birtakm parametreler alp buna gre bir deer dndrr. Fonksiyon yazmnda kodun begin-end aralna alnmas zorunludur. Fonksiyonlar arrken fonksiyon adnn bana ema adnn konulmas zorunludur.

CREATE FUNCTION uf_SehirKoddanSehirAdGetir(@sehirKod AS int) RETURNS varchar(50) AS BEGIN DECLARE @sehirAd varchar(50)

SELECT @sehirAd = SehirAd FROM Sehir WHERE SehirKod = @sehirKod RETURN @sehirAd END SELECT dbo.uf_SehirKoddanSehirAdGetir(34) SELECT MusteriNo, MusteriAd, dbo.uf_SehirKoddanSehirAdGetir(34) AS SehirAd FROM Musteri Burada ehirAd' imdiye kadar hep Sehir tablosu ile Musteri tablosunu JOIN ederek elde ettik. Ancak yukardaki sorguda nceden yazdm bir fonksiyon bu ilemi yerine getirdi.

-- Sehir No'su girilen sehre kaytl tm musterileri dndr. ALTER FUNCTION uf_SehirKodDondur(@sehirAd AS varchar(50)) RETURNS int AS BEGIN DECLARE @sehirKod AS int SELECT @sehirKod = sehirKod FROM Sehir WHERE SehirAd = @sehirAd RETURN @sehirKod END SELECT MusteriAd FROM Musteri WHERE SehirKod = dbo.uf_SehirKodDondur('zmir') SELECT MusteriAd, dbo.uf_SehirKoddanSehirAdGetir(dbo.uf_SehirKodDondur('zmir')) AS SehirAd FROM Musteri WHERE SehirKod = dbo.uf_SehirKodDondur('zmir')

upper() fonksiyonu kendisine verilen bir karakter setinin tamamn byk harfe evirir, lower() da bunun tersini yapyor. len() fonksiyonu string'in uzunluunu verir.

LER SQL KURSUNUN KONULARI SSIS (Sql Server Integration Services) = Statik ve dinamik raporlama yaplmasn salar. Bir ok DB'den bir dataware house (veri ambar) hazrlanr ve zerinde ilemler gerekletirilir. SSAS (Sql Server Analysis Services) = Dinamik raporlama iin kplerin oluturulduu ve veri zerinde analiz yaplmasn salayan bir ara. Ayrca raporlar dinamik olarak oluturulabilir. SSAS'nin ierisinde data mining zellii de vardr.

SSRS (Sql Server Reporting Services) = Statik raporlama iin kullanlr. -------------------------------------------------------------------------------------------------- Fonksiyonlar geri dndrdkleri yapya gre e ayrlr: scalar functions, tabular functions, table-valued function.

Tabular fonksiyon rnei CREATE FUNCTION uf_SehirMusterileriniGetir(@sehirKod AS int) RETURNS TABLE AS RETURN (SELECT MusteriNo, MusteriAd, Bakiye FROM Musteri WHERE SehirKod = @sehirKod) SELECT * FROM uf_SehirMusterileriniGetir(34)
Tabular Function'lar parametre alan bir view gibi dnlebilir ve kullanlabilir.

ALTER FUNCTION uf_SehirMusterileriniGetir_AdaGore(@sehirAd AS varchar(100)) RETURNS TABLE AS RETURN (SELECT MusteriNo, MusteriAd, Bakiye FROM Musteri WHERE SehirKod = dbo.uf_SehirKodDondur(@sehirAd)) SELECT * FROM dbo.uf_SehirMusterileriniGetir_AdaGore('stanbul') Table-valued Function rnei CREATE FUNCTION uf_SehirMusterileriniGetir_AdaGore2(@sehirAd AS varchar(100)) RETURNS @sehirMusteri TABLE (MNo int, MAd varchar(100), Bakiye decimal(8,2) ) AS BEGIN -- Baka ilemler burada yaplabilir INSERT INTO @sehirMusteri SELECT MusteriNo, MusteriAd, Bakiye FROM Musteri WHERE SehirKod = dbo.uf_SehirKodDondur(@sehirAd) END RETURN

13 Eyll 2008 View'ler genelde INSERT ilemleri iin kullanlmaz. Karmak sorgular basit hale getirmekte ara olarak kullanlrlar. Trigger programatik olarak yakalanamaz. Server'da gerekleen Programatik olarak yakalanmasn gerektirecek bir durum yok. bir ey.

SQL SERVER'DA GVENLK (SECURITY)


Bir veritaban ile alrken bir gvenlik yntemi seilir. Bunun DBMS bize baz klar sunar, bunlar kullanlabilir ya da biz kendimiz tamamen kendimize ait bir yap kurabiliriz. Kk bir iletmede veritabanna bir ka farkl ekilde eriilir: a) Sistem yneticisi eriir. b) Bir programdan eriilir. SQL Server ilk kurulduunda iki tane admin login'i vardr. Belli kullanclarn nce yaratlmas gerekir. Ancak bu admin login'leri program kurulurken yaratlmtr. Bunlarn isimleri: Builtin Administrator: Makinadaki lokal admin grubunun login'idir. O makinada kimler admin ise bu login'i onlar kullanr. Yani, bu login tr SQL

Server'n kurulu olduu makinann admin'lerine hitap eder. (Bir domain'in admin'leri de SQL Server'n admin'leri olur.) sa: Mixed mod'da kullanlabilir durumdadr.

(Tm Windows makinalarnn kendi kullanc db'si vardr. SQL Server'da da durum byledir. Ancak, network'te bir makinann kullancs dier makinay kullanmak isteyebilir. Domain yaps olmayan makinada Ali'nin Veli'ye erimesi iin ali'nin veli'nin makinasnda ayn ad ve ifre ile yaratlmas gerekir. (Workgroup mant) Ayn ey veli, can, ahmet iin de geerli. Bu sebeple merkezi bir kullanc db'sinin olmas mantkldr. Bunun iin merkeze bir windows server kurulur ve kullanclar bu server'da saklanr, ve saklandklar db'ye active directory denir. Bir kullanc artk dierine erimek istediinde artk ortak db'yi kullanr. Bu yapya ise domain yaps denir. Server'n zerinde Domain Admins bulunur. (Lokal kullanclar halen duruyor) Domain Admins grubu admin'leri ayn zamanda her makinann admin grubuna yedir. Bir SQL Server kurulunca bu makinannda kendi local admins'i var ve buna Built-in Administrator SQL Server'da oluturulur. SQL Server'da login'leri yaratrken Network'te kullanclarn tanmlar active directory'de. Bunlar dorudan sql server'a ekleriz. Windows Authetication'da ise Windows kullanclar login olurlar. Yani sadece lokalda tanml kullanclar kaytl olur. SQL Server'n gvenlik ayar (security setting) iki farkl ekilde yaplabilir. Birincisi mixing mode'dur. Eer bu seilmi ise sa adnda bir kullanc vardr. Bu deilse sa gzkr ama kullanlmaz. Dier ekil ise (mod) Windows Authentication Mode'dur. Mixed Mode: Domain kullanclar dnda kullanclarn da sql login'i olsun istersek Mixed-mode'u seeriz. Mixed-Mode'un dier ad "Windows Authentication + SQL Authentication"dr. Object Explorer'da db adna sa tkla ve security'yi a. Burada server'n security mode'u grlebilir. Bir program ile de Sql Server'a eriilebilir. O program iin de birtakm yetkiler belirtilir. Program biz yazyorsak: Bu durumda bir ka seenek var: 1) Birincisi connString olarak program db'ye sa olarak balanr. 2) Programn ierisinde kendimiz bir gvenlik yaps kurarz. Bu yap, db'de bir User tablosu vardr ve programn programcsn buraya ekleriz, bir de programdaki nesneler vardr. Bunlarn string olarak isimlerini gireriz. Bir dieri de yetki tablosu olabilir. Pencerelere girme yetkisi, update etme yetkisi gibi. Bir de kullanc yetkisi: Hangi programcnn hangi nesnede ne yetkisi var gibi ? 3) Daha byk sistemlerde bir ok kii SQL Server tablolarna bir ok kullanc eriecekse gene ikinci k kullanlyor olabilir, ya da SQL Server'n nesnelerine yetki vermek isteyebiliriz. Bu durumda, baka kullanclar SQL Server'a login olarak eklenir ve bunlara tablolar baznda yetki verilir. Yani, sa'dan baka domain'deki ali SQL Server login'e eklenir ve ali'ye sadece fatura tablosundan okuma yetkisi verilir. SQL server'da gvenlik denildiinde yukardaki maddelerden ncs kabul edilir. Gvenlik bal altnda biz bu nc durumu deerlendireceiz. SQL Server nesnelerine yetkilendirme yaparken olay gerekleiyor: SQL Server'da gvenlik yapsnn kurulmas : bir ka aamada

1) Login'leri ekleme: a)Domain dndaki kullanclarn login olarak eklenmesi. Artk bunlar SQL Server'a balanabilirler ancak hi bir i yapamazlar nk b) bu login'ler iin ayrca kullanacaklar db'lere user olarak eklenmelidir. (bir login'in user olarak eklenmesi.) b-2) O user'larn SQL Server'da o db'ye role verilmesi gerekir. (Kullanclara tek tek tablo atamaktaysak, onlara birer role veririz.) SQL Server'n kendi ierisinde standart bir role vardir: ad public'tir. DB'ye User olarak eklenen herkesin role' default olarak public'tir. (Public role' ile DB'nin kendi nesnelerini grebilir ama tablolara yetkisi olmaz.) c) DB'de tablolarda ve programlama nesnelerinde user'a yetki verilir. Hseyin Hoca 3. maddeyi nermiyor. d) DB'de roller yarat e) Rollere yetki ver f) User'lar rollere ye yap. nerileni byle yaplmas. login'ler server dzeyindedir. Bu login'ler db'lere eklendiklere buna user denir. Bir user'n login'i silinirse o user orphan kalr. Bir login eklenip ksz kalan user'a sonradan yeni bir login yaratp verebiliriz. Bilgisayar > Ynet > Yerel kullanclar > yeni'den domain'de yeni kullanc tanmla. SQL Server > Security Login > New Login > search > gelimi > imdi bul > ... ekle. Artk bu kullanc SQL Server'a balanabilir. Onun bir login'i oldu. Sonra: Security > Users > New USer > login'inde button'u tkla > se ve ekle. eklenen kullanclara her trl yetkiyi vereceksek tablo adna sa tkla properties > permissions > browse'tan ekle ve yetkilerini ver. Artk Windows'a log olan farkl kullanclar kendilerine verilen yetkiler lsnde SQL Server' kullanabilirler. Ancak, bu ekilde tek tek yapmakla kullanc says byynce baa klamamaya balanr. Bunun iin Security > Role > New Role Ya da Security > Login > New Login > Sim gir ve SQL Authentication ile gir. te bu kullanc Windows'ta ya da domain'de tanml bir kullanc deil, sadece SQL Server'a eklenen bir login laveten Server Roles adnda bir balk var. DB'deki her yetki istendiini dnelim: Server role'lerden sysadmin yaparsak ve adna Bulk admin toplu halde veri aktarr, dbcreater db yaratr, diskadmin db'ye dosya eklleme vb., processadmin kill etme gibi ilemler yapar, process'leri kontrol eder etc... Database iinde de role'ler var: (Security > Roles > Database Roles) db yetkisi alma, dbreader: tm tablolardan okuma yapar, dbwriter yazar, ddladmin ddl ilemlerini yapar, denydatareader yesi hi bir okuma yapamaz, denydatawriter hi bir tabloya yazma yapamaz, owner db'nin sahibidir, securityadmin yetkilendirme yetkisidir ancak genelde buradaki roller ok sk kullanlmaz. Rolleri genelde kendimiz tanmlarz.

nesneler iin yetkiler: user'a yetki ya da user'lara roller verebiliriz. Table Properties > Permissions'tan ayarlar yaplr. Burada References yetkisi: eer bir tablo dier tabloya foreign key ile balysa bir tablodakinin dier tablodaki data'y okumas gerekir. Yetkisi olmasa da foreign key'nin gsterdii yere referans alarak okuma izni veren ayardr. Take OwnerShip; nesnenin sahiplii alabilme yetkisi. View Definition yetkisi tablonun tanmn grebilme yetkisidir. Yetkilendirme ayarlarnda "Grant" yetkiyi verir, "Deny" baka bir rolden dolay bu tabloyu grme yetkisine sahipse yani baka yerden bir yetki gelse bile o kii deny edildii tabloya eriemez. "With Grant" ile hem kiiye yetki verilir hem de yetki verilen bu kii bakasna da yetki verebilir. stersek Table Properties > Permissions'tan kolon baznda yetkiler verebiliriz. Ancak kolon baznda yetki vermek yerine genelde ayn ii grmesi iin View kullanlr. Windows yetkilendirminde Group'lar vardr. Mesela Muhasebe Grubu gibi. Bir makinadan dierine grup baznda yetki verilir. Ayn ekilde SQL Server'da da Muhasebe grubu tanmlanr. Bir muhasebe rol tanmlanr. Problem modler ekilde zlm olur. Bilgisayarm > Ynet > Yerel kullanclar > Gruplar > Yeni Grup ile Windows'a grup eklenir.

mstsc = uzaktaki makinaya eriim programn altrr. Security > Login'den yeni grup eklenir. Grup eklendikten sonra DB'den > uSer > New User'dan eklenen grup seilecek. Artk bu grup user'na verilmi tm yetkiler gruptaki tm kullanclara verilmi olur.

Excel > Aralar > D Veri Al...> yeni kaynak > ile o makinadaki veri kaynaklarndan veri alnabilir.

BACKUP
Veritaban adna sa tkla > tasks > backup ile yaplr. Backup'n bir alternatifi yok. Kk bir iletmenin her gn db'nin full yedeinin alnmas gerekir. DB'nin yedei alnd o db ile ilgili tm bilgiler (sp, trigger, user'lar gibi) yedeklenir. Login'ler ise masterdb'de tutulur. Dolaysyla masterdb'nin de yedei alnabilir. Her DB kendi bana yedek alnr. Full backup almak ok uzun srer. Bu sebeple gnde bir full backup alnrken saatte bir transaction log alnabilir. DB alrken backup alnabilir hatta zerinde allrken restore dahi yaplabilir. Transaction log yedekleri en son alnan yedekten sonraki yedekleri tutar. Eer gnde 1 full ve saat ba transaction yedek aldysak nce full yedek kurulur ardndan sras ile transaction log'lar kurulur.

Differential log bir nceki full yedekten sonraki tm yedekleri alr. Yani saat 24'de full, saat 5'te differential ve 5:30'da transaction log alndysa bunlar sras ile geri yklemek gerekir. st ste 2 defa differential yedek alrsak sonraki ncekini ierir. Tm db'nin yerine tablo baznda yedek de alnabilir. Tm yedekler ayn dosyaya yazlabilir. Full ve transaction'lar ayn dosyaya alnabilir. Backup' geri dndrmek iin Tasks > Restore seilir. Burada Recovery State'e dikkat etmek gerekir. Restore edilen db'nin operasyonlara almas iin en stteki k seilmelidir. (Leave the db ready to use, ikincisi seilirse yukardan overwrite existing db seilmelidir. Restore edilirken RESTRICTED_MODE alnmas nerilir. Bylece o db'de baka bal olanlara kstlama yaplm olur.

14 Eyll 2008 CREATE LOGIN [MakinaAd\KullancAd] FROM WINDOWS => Makinadaki domain'deki kullanc iin SQL Server'da login yaratr. nce login yarattk(login server baznda yaratlr), db'ye eriim izni verdik. Sonra db baznda user tanmladk ve birtakm rnein tablo eriim yetkileri verdik. Bu ilemin tekrar tekrar yaplmas youn i ortamlarnda zorluk yaratabilir. Bunun yerine role'ler yaratlp kullanlabilir. Bu role'ler de db baznda yaratlr. Server bazndaki roller sabittir, ne yenileri eklenebilir ne varolan roller silinebilir ne de bu rollerin ierikleri deitirilebilir.

USE [master] GO CREATE LOGIN [lambert\acuna] FROM WINDOWS -- Yeni login ekler. DROP LOGIN [lambert\acuna] -- Login'i kaldrr. CREATE USER [acuna] FROM LOGIN [lambert\acuna] USE hbb GRANT SELECT ON [dbo].[Stok] TO [acuna] verir. -- Tablo baznda kullancya yetki

USE hbb CREATE ROLE MuhasebeRol AUTHORIZATION [dbo] EXEC sp_addrolemember N'MuhasebeRol', N'acuna' -- Bu sistem sp'si ile bir kullanc bir role atanr. Role kullanc uyumsuzdur. ekleyen sistem sp'si ANSI Standardna

sp_addrolemember

Genelde SP implementasyonlarnn en banda set nocount on script'i yazlr. Bunun kullanlma sebebi sp exec edildiinde baar durumu iin bir mesaj

dndrr normalde ancak bu da makinann fazladan ilem yapmasna sebep olur. Bu script paras sp'ye eklendi mi artk bu mesaj dndrlmez. Security > Login > New Login'de Server Roles ve User Mapping sekmelerinden yetkilendirme ilemini ksa yoldan yapabiliriz. GO => Baz komutlarn arasnda ayra vazifesi grr, yani GO'dan nce ve sonra birer komut geliyorsa nce gelen nce alr, ve sonra gelen sonra alr.

DECLARE @a int SET @a = 1 SELECT @a GO SELECT @a

-- Go'dan sonraki sorgu nceki sorgudan sonra ele alnaca iin SELECT @a sorgusu deiken tanmlanmad hatas verir.

Alnan backup'larn birimi set'tir. Birden fazla backup set'i dek bir dosyann iine yazlabilir. Recovery State 3'e ayrlr: kinci seenek restore ettim ancak henz kullanclara ama, daha baka restore'lar yapmaya devam edeceim anlamna gelir. Ne zamanki son restore'a geliriz, bu restore'u ilk k ile seerek hem restore ilemini gerekletiririz hem de DB'yi kullanclarn kullanmna aarz. Birinci k restore eder, transaction log'daki commit edilmemi tran'lar commit eder ve kullanma aar. kinci k, backup' restore eder ama tran log'daki commit edilmemi tran'lar commit etmez. nk birazdan bir restore daha yapacaz ve o zaman bu commit edilmemi tran'larn commit edilmesi gerekiyor. BEGIN TRAN DELETE Stok Bu tran commit edilmemi. te bunun gibi commit edilmemi tran'larla ilgili davranlar yukarda anlatlmtr. (Full yedei aldmda tran commit edilmemi ancak transaction log backup'n restore ederken orada bu tran commit edilmi. te bu durumda full backup restore edilirken ikinci k seilir ve commit edilmemi tran gene tran edilmemi olarak braklr. kinci transaction log backup' restore edilirken bu tran iki backup arasnda commit edilmi olsa da olmasa da ilki seilir ve o tran'n commit edilmesi garanti altna alnr.

nc kta db read-only olarak restore edilir. Commit edilmemi tran'lar gene commit edilmez ama aasnda belirtilen adrese yedekler. Restore DB menusunde To Point In Time ile DB'yi belirtilen zamana geri alabiliriz. DB'ye sa tkla > Tasks > Generate Scripts ile tm db'nin script'i iindeki data olmadan retilebilir.

BACKUP N JOB YARATMA: Backup ileminin script'ini al. New Job Step ekle ve Command alanna bu script'i yaptr. Artk job yaratlmtr. Bunu bir schedule'e balamak iin yaratlan iin zerine sa tklayp new job schedule ile schedule'e balayabiliriz.

MAINTENANCE PLAN OLUTURMA (BAKIM LEMLER) Management > Maintenance Plan > New > sim ver / Bir schedule ver. Maintenance'da DB Shrink edilir, Integrity check yaplr, indeksler reorganize edilir, index'ler rebuild edilebilir, db backup' alnabilir, history temizlenebilir, Maintenance Cleanup Task oluturulabilir.

Extended Procedures: C dili ile yazlm kodlar bir .dll halinde SQL Server'a eklenip extended procedure olarak kullanlabilirler. Ancak biz bu ii zaten CLRSQL ile yapacaz. Maintenance Plan Wizard Kullanm Maintenance Plan Wizard mod'da srkle brakla oluturulabilir. nce Check Database Integrity Task konur sonra Rebuild Index Task oluturulur (Rebuild Index ile baz kaytlarn silinmesi ile db zerinde bir fragmentation oluur. [8K'lk page'lerden oluan db ile silinen page'ler btn zerinde boluklar oluturur] Rebuild index ile defragmentation yaplr > Backup Database Task konulur > Notify operatr task konulup baarszlklarda notification rettirilebilir. Wizard'da diyagramlar ve aralarndaki link'ler grsel olarak ayarlanabilir. > Pencerenin st ksmndaki menuden schedule seilip ayarlanabilir. Tm bunlar bir subplan ad altnda oluturulur. Ayn Maintenance Plan'a n tane subplan eklenebilir. > Execute T-SQL Statement Task konulur:

INDEX'LER
Alt balklar: 1) Index'lerin planlanmas: Nerelere index konulur ve bu nasl yaplr. WHERE clause 'da ieren bir sorgu olduunu dnelim. Burada SQL Server WHERE koulunu nasl arar ? Sral olarak arar. (O(n)) Bunun yerine adres defteri misali sral olsayd aranan kayda ok daha kolay ulalrd. Tablodaki kaytlarn primary key'lerine gre alfabetik srada olduklarn dnelim ve her harfin BTree veriyapsnda bir parent node yerine getiini dnelim. Bulmak ok daha kolay olacakt. (Burada Binary Search ile gidiyor.) Verilerin belli bir sraya uyacak ekilde yazlmasna indeksleme denir. Tm satrlarn DB'de saklandklar veriyapsnn yapsna uygun olarak sralanmasna clustered index denir. rnein yeni satr eklendiinde bu kayd en sona deil de veriyapsndaki doru yere ekler. (Telefon defteri clustered index rneidir)) Adres defterinden bir numaraya gre kayt bulmak istiyorsam (liste isme gre sral) peki ne yaplacak ? O zaman yeni bir rehber yapp tel no'ya gre sralamak masrafl. Bunun yerine ayn tabloya numaraya gre de bir index koyarz. Peki her iki koula gre de ayn tablo nasl bir sraya sahip olacak ? Bu durumda ilk indexleme koulundan sonraki indeksleme koullarn SQL Server'n kendisi sahte bir tabloda tutar. Bylece artk biz numaraya gre de eriim yapabiliriz. te byle indekslere non-clustered index denir. Bylece bir tabloda n tane index oluturabiliriz. lk oluturulan index clustered index olur, sonraki index'ler ise nonclustered index olarak oluturulur. Clustered index primary key'e gre yaplr. Dolaysyla doal olarak bir tabloda tek bir clustered index bulunur. Biz istersek clustered index'i non-clustered yapp non-clustered'lardan birini clustered index yapabiliriz. Tm non-clustered index'ler clustered index'e bakarak oluturulur.

Dolaysyla clustered index deitirilirse tm non-clustered index'ler yeniden oluturulur. ndeksleme ile ORDER BY'n yk yksek dzeyde hafifletilir. ORDER BY kullanacamz kolonun indekslenmesi yksek performans kazanc salar. GROUP BY yaplan kolonlarn indekslenmesi gerekir. WHERE Clause'unda sklkla kullandmz kolonlar indekslenmelidir. FOREIGN KEY'ler muhakkak indekslenmelidir. nk JOIN ilemi bir tablodaki PK ile dier tablodaki FK arasnda eitlikler ile yaplr. Bir indeks kendi iinde birtakm iler yaptndan bir maliyete sahiptir. (Arkaplanda sahte tablolarda sralama oluturmas gibi) SQL Server'da Index Treeing... arac ile alma zamannda yaplan tm ileri log'layan bir profiler ile index tree oluturulabilir. Ancak bu ara belli zaman araln log'lar. Composite Index'ler konulabilir. rnein StokKod ile Fiyat ya da Ad ile Soyad kolonlar iin tek bir indeks oluturulabilir. Composite indekslemede sra sorgudaki sra ile ayn olmaldr. Bir kolona iki indeks konabilir. UNIQUE kst ile bir index otomatik eklenir. Index yaratlacak kolonun selectivity'si yksek olmaldr. (Cinsiyet kolonu pek mantkl deil.) CREATE NONCLUSTERED INDEX [IDX_StokFiyat] ON [dbo].[Stok] ( [Stokfiyat] ASC ) ON [PRIMARY] Index konulduunda Execution Plan'de Table Scan yerine Index Scan yaplr. Stored Procedure'lerde indekslerle ilgili alma plan sadece bir kez yaplr. Bu sebep SP'lerin kullanlmasnda nemli bir gerekedir. Script yoluyla bir index'in kullanlmasna zorlama yapabiliriz.

20 Eyll 2008 ki tr index var: Clustered ve non-clustered. Bir tabloda 1 tane clustered index olabilir ve maksimum 249 tane non-clustered index olabilir. ORDER BY | GROUP BY | FOREIGN KEY'lerde index kullanmak gerekir. PK'larn index'leri mutlaka clustered index olmak zorunda deildir.

Composite Key'lerden olumu composite key'ler olabilir. WHERE ad = ? AND soyad = ? gibi sorgularda composite key konulabilir ve composite index sras sorgudaki sra ile ayn olmal yoksa o sorgu o index'ten faydalanamaz. ORDER BY adi dersek soyad, ad'dan oluan bir composite key'den faydalanr.

INSERT, UPDATE, DELETE komutlar da index'lerden faydalanr. Index'ler tablodaki kolonlar baznda alr. rnek bir index scripti: CREATE NONCLUSTERED INDEX IX_BolgeNo ON Sehir(BolgeNo) Burada NONCLUSTERED NONCLUSTERED'dr. yazmak zorunlu deil. Zaten default'

Query Optimizer index'lerden hangisinin kullanlacana nasl karar verir ? RDBMS buna bir karar vermek zorunda. RDBMS buna karar vermek iin internal olarak kolonlara ilikin istatistikler tutar. O istatistiklerde kolonun density'sine (younluuna) bakar. rnein soyada gre bir index varsa RDBMS o index'e ait kolon iin bir istatistik oluturur. En youn density'ye sahip index'i kullanr. DBCC show_statistics(Sehir, IX_BolgeNo) -- RANGE HI_KEY'deki kolon deerininin ka defa getii EQ_ROWS'ta yazyor. RDBMS'e istatistikleri olutur dediysek oluturur. SQL Server kurulumunda bu ayar default aktr. Database Properties > Options > Auto Update Statistics ile bu ayar deitirilebilir. Eer bu false ise index oluturulduunda gene istatistik oluturulur ancak update edilmez. Bizim update ettirmemiz gerekir. statistikleri biz update edebiliriz ya da SQL Server zaman zaman update edebilir. Bunun iin Auto Update Statistics opsiyonuna bakar. Eer DB'de Auto Update Statistics true ise otomatik olarak indeks olmasa bile JOIN'deki ON'un sa taraf kolonu iin istatistik tutar. Manuel olarak istatistik update ilemi Rebuild Indexes kk seilerek yaplr. Bir index'i istersek UNIQUE yapabiliriz. Bir kolona UNIQUE kst verildiinde orada otomatik olarak bir index oluturulur. Rebuild ilemi ALTER INDEX IX_BolgeNo ON Sehir REBUILD eklinde bir script ile yaplr. Index'ler neden rebuild edilir ? Index'ler bir BTree yapsnda tutulur. Bir index'i sildiimizde, gncellediimizde ya da yeni indeks eklediimizde veriyapsnda birtakm boluklar oluabilir. Diskte rastgele bo bulduu bir yere yazabiliyor. Biz rebuild index yaptmzda bir nevi defragmentation yapar. te bu sebeple Index'ler rebuild edilir. SQL Server verileri 8KB'lik page'lerde saklar. 8 tane 8KB'lik page'e bir extend denir. rnein ehir tablosunun bir satrnn uzunluu 40 byte. Yani bir page'e n tane satr ekleniyor. Ne zamanki page dolarsa baka bir page daha aar. Yani

page split edilmi olur. Bir tablodaki 200 satr kayttan 100 tanesini bir page'de dier 100 tanesini baka bir page'de tutmu oluyor. RDBMS index'lere kar da ayn ekilde davranyor. Bir page'e aa yukar 700 index sar. Ne zaman 700 index'ten fazlas gelir. Bunlar dier page'e yazyor. Yalnz bir detay olarak 12K veri varsa birinci page'de 8K dierinde 4K tutmuyor. Her ikisinde de 6'ar K tutuyor. Bu alma ekli ile bazen dizilimlerde bo yerler oluuyor. Rebuild edince blnen page'leri toparlar, index'ler aras fragmantasyonlar defragmante eder. Rebuild ilemini genellikle maintenance job'lar yapar. Index'te tutulan ey Hangi file'daki hangi extend'deki hangi page'deki hangi row olduu bilgisidir. Index'leri sadece defragmante eden bir ayar da vardr ancak Rebuild etmek daha mantkldr. Data stnde ok sayda INSERT, UPDATE, DELETE yaplyorsa Rebuild etmek gereklidir. ALTER INDEX gerekletirilir. IX_BolgeNo ON Sehir REBUILD script'i ile rebuild ilemi

Eski rebuild sentaks: CREATE INDEX IX_BolgeNo ON Sehir(BolgeNo) WITH DROP EXISTING Set Fill Factor: Bir index'i olutururken page'in ne kadarn bo braksn. (A'dan Z'ye kadar tm index'imiz bir page' syor olsun. Ancak o page'e baka data'larda eklemek istiyorsak Fill Factor' %100'n altnda bir deer yaparz. Bu deere kadara kadar o page'e index konulur, gerisine data konulur.) Youn update edilen tablolarda Fill Factor dk tutulmaldr. Index'in bir satr 900 byte'a kadar kabilir. Index Properties > Included Columns = Bir sorgudaki tm satrlar zaten index'in iindeyse bu durumda sorguyu iletmesi iin tablonun kendisine gitmesine gerek kalmaz. Yani eer Sehir tablosundaki BolgeNo'yu fetche diyorsak ve gene BolgeNo'ya gre fetch ediyorsak bu sorgu iin tabloya gitmez. SELECT BolgeNo FROM Sehir ORDER BY BolgeNo => Burada tabloya gitmez. SELECT BolgeNo, SehirAd FROM Sehir ORDER BY BolgeNo => Burada da tabloya gitmez. BolgeNo'nun yannda SehirAd' da tutar. Ama SehirAd index deildir. Bir included column'dur. Eer SehirAd included column deilse yukardaki sorguda BolgeNo'yu index'ten alr, SehirAd' tablodan alr.

DB birden fazla dosyada duruyorsa index'lerle tablolar farkl dosyalarda tutmak faydaldr. O anda bir kolona dair unique olmayan satrlar varsa SQL Server UNIQUE kst koymamza izin vermez. UNIQUE kst ile UNIQUE index arasndaki fark: UNIQUE index'inde duplicate value'leri grmezden gel diyebiliriz. Ancak kstta izin vermez. UNIQUE kst aadaki script ile konulabilir:

ALTER TABLE Personel ADD CONSTRAINT UQ_PersonelAd UNIQUE(PersonelAd) Bir tabloda UNIQUE'lii bozan kaytlar aadaki sorgu ile bulunabilir: SELECT COUNT(*), PersonelAd FROM Personel GROUP BY PersonelAd HAVING COUNT(*) > 1

SYNONYMS (TAKMA ADLAR)


-- Bir DB'den baka bir db'ye erimek iin [dbad].[emaad].[tabload] yazmak gerekir. Byle yazmak yerine -uzun olabilir nk- bu isme bir takma ad oluturabilir. Synonym > New Synonym ile bir synonym oluturulabilir. emay bir DB'yi sanal olarak alt-db'lere blmek iin kullanabiliriz. Ya tm data'lar ayn db'dedir ve emalara gre gruplanmtr. Ya da firmalar iin bir db varken her bir ema bir firma olabilir. Ya da departman baznda emalar kullanlabilir. emalar Object Explorer'da Security balnn altndadr. Bir user bir nesne yarattnda bunu kendi emasnda yaratr. Default ema, ema belirtilmedike [dbo] emasdr. Bu ema zeldir. Herhangi bir kullanc bir nesneye erimek istediinde nce kendi emasnda aranr, bulunamazsa [dbo] emasna baklr. ema yaratmak iin kullanlan ema: CREATE SCHEMA <ema_Ad> ema baznda verilen bir yetki o emadaki tm nesneler iin verilmi olur.

SQLCLR
Regex iin SQLCLR kullanlabilir. Surface Area Configuration'dan CLR Integration' enable yap. VS'de Database Project > SQL-CLR se. Bir SQLCLR projesi deploy edilince Object Explorer'da Programmability > Assemblies'e projenin .dll'i eklenir. Yazlan prosedr de Stored Procedures'e eklenir. Tutulanlar image veri trnde tutulur.

public partial class StoredProcedures { [Microsoft.SqlServer.Server.SqlProcedure] public static void GetTableData(string tableName) { SqlConnection conn = new SqlConnection("context connection=true"); conn.Open(); SqlCommand dbCommand = new SqlCommand(); dbCommand.Connection = conn; dbCommand.CommandText = "SELECT * FROM " + tableName; SqlPipe pipe = SqlContext.Pipe;

pipe.ExecuteAndSend(dbCommand); } conn.Close();

public partial class UserDefinedFunctions { [Microsoft.SqlServer.Server.SqlFunction] public static SqlString SayHello(string str) { // Put your code here return new SqlString(str.ToUpper()); } }; public partial class Triggers { // Enter existing table or view for the target and uncomment the attribute line [Microsoft.SqlServer.Server.SqlTrigger(Name = "Triggers", Target = "Bolge", Event = "FOR DELETE")] public static void Trigger() { SqlConnection conn2 = new SqlConnection("context connection=true"); conn2.Open(); SqlCommand dbCommand2 = new SqlCommand(); dbCommand2.Connection = conn2; dbCommand2.CommandText = "INSERT Book SELECT BolgeAd FROM DELETED"; dbCommand2.ExecuteNonQuery();

SON K HAFTAK DERSLERE GRMEDM. NOTLARDA SON K HAFTA EKSKTR.

You might also like