18 Mart 2017 Cumartesi

SQL Server Monitoring

Merhaba Arkadaşlar,

Bugün sizlere SQL Server'da monitoring neden yapıyoruz, monitoring yaparken hangi toollardan faydalanmaktayız gibi konulardan bahsetmek istiyorum.

Monitoring, ingilizcede izleme, gözlemleme anlamında kullanılmaktadır.

Neden Monitoring Yaparız?


 Dba'ler, SQL Server'ı anlık ve oluşabilecek sorunlara çözüm üretmek ve server'ın performanslı bir şekilde sürekliliğini sağmak için monitoring yapmaktadır. Monitoring yaparak serverımızın anlık ve geçmiş durumunu izleyebiliriz. Örnek verecek olursak; Kaynak kullanımı, disklerin doluluk oranı, hangi sorgu daha az performans vermekte, nerelerde deadlocklar oluşmuş, veritabanı büyümesi gibi durumları monitoring yaparak kontrol edebilmekteyiz.

Genel olarak her dba, bir veritabanı planlaması yaparken öncelikle hangi iş yükünün ne kadar kaynak kullanması gerektiğini tespit eder ve buna uygun kaynak dağıtımı yapar. Daha sonra server'ın stabil çalıştığı durumu gösteren bir taban değer belirler ve ileride oluşabilecek sorunlara karşı bu değeri karşılaştırarak çözüm üretir. Bunun yanısıra, serverın devamlılığı için önemli olan donanımların takibiyle beraber, gerekli durumda donanım upgradelerini yapmaktadır.

Günümüzde monitoring yapmak için pek çok program mevcut. Ben bugün sizlere Microsoft'un ve SQL Server'ın bize sunmuş olduğu toollarla monitoring işlemlerini nasıl yapıyoruz ondan bahsedeceğim.

Activity Monitor


SQL Server'ın bize sunmuş olduğu bu tool ile serverın anlık ve geçmiş izlemelerini yapabilmekte, kaynak kullanımına, data file okuma yazmalarına, ağır querylere ait bilgileri edinebilmekteyiz. Bunun için view server state iznine sahip olmamız gerekmektedir.

Server üzerine sağ tıkladıktan sonra Activity Monitor seçeneğine basarak bu tool'u açıyoruz.


























Karşımıza 6 adet sekme çıkmakta,




Overview

Bu bölümde genel olarak bize bir bilgilendirme yapmaktadır. Burada; işlemci zamanını, bekleyen taskların kaç adet olduğunu, database üzerindeki okuma yazmaları(mb/saniye bazında), gelen query ve batch isteklerinin adedini(saniye bazında) ilgili alanlar üzerinden görebiliyoruz.


Processes

Bu bölümden sessionları takip edebiliyoruz. Session'la ilgili, login name, hangi database üzerinde olduğu, hangi uygulamayı kullandığı, host adı gibi bilgilere ulaşabilmekteyiz. Örneğin bir deadlock oluştuğunda bunu  blocked by sekmesi altında deadlock'a neden olan session'ın id'sin hangi session'ın hangi session'ı blokladığı bilgisine ulaşabiliyoruz.


Resource Waits

Bu bölümde kaynak kullanımlarıyla ilgili ögeler mevcut. Buffer I/O, Logging, Memory, Network I/O gibi ögelere ait bekleme sürelerini buradan görebiliyoruz.

Data File I/O

Bu bölümde, server'ın data dosyalarının okuma yazmaları(mb/saniye) ve tepki sürelerinin(ms) takibini yapabilmekteyiz.

Recent Expensive Query

Bu kısımda çalışan ağır sorguları görmekteyiz. Sorgunun, dakikada kaç defa çalıştığı, Cpu kullanımı, fiziksel ve mantıksal okumaları, fiziksel yazmaları, hangi database üzerinde olduğu gibi bilgilere ulaşabiliyoruz.


Dynamic Management View ve Functionlar ( DMV/ DMF)


DMV ve DMF'ler SQL Server'ın iç durumuna ait bütün bilgileri içermektedir. Activity Monitordeki değerler de aslında dmv dmf'lerle bağlantılıdır. 2005 öncesinde bu bilgileri izlemek için third party yazılımlar kullanılmaktaydı. Fakat kötü yazılmış bu yazılımlar serverların çökmesine kadar kötü etkiler yaratabiliyordu. SQL Server 2005 ile gelen dynamic management view ve functionlar sayesinde bu yazılımlara gerek kalmadan istenilen performans verileri elde edilebilmektedir. 

2 çeşit dmv ve dmf vardır. Bunlar;

  • Server bazlı bilgileri barındıran ve view server state izni gerektirenler
  • Database bazlı bilgileri barındıran ve view database izni gerektirenlerdir.
Bunlar sys şeması altında tutulmaktadır. Saklı olan resources sistem veritabanında bulunur ve diğer veritabanlarıyla eşleştirilir. Bunlara örnek vermemiz gerekirse;

  • sys.dm_exec_% kategorisi altında sys.dm_exec_sessions --Server'a bağlı olan bütün sessionları döndürür.
  • sys.dm_os_% kategorisi altında sys.dm_os_performance_counter --İşletim sistemi araçlarını kullanarak sql server performans sayaçlarına erişimi sağlar.
  • sys.dm_io% kategorisi altında sys.dm_io_virtual_file_stats -- Veritabanı için dosya I/O istatistiklerini verir.
Çeşitli kombinasyonlarla istediğimiz performans izlemelerini yapabilmekteyiz. 


Performance Monitor


Microsoft'un bize sunmuş olduğu performans izleyici sayesinde gerek işletim sistemini gerek sql serverı izleyebilmekteyiz. Performans izleyicisini açmak için windows+r tuşuna bastıktan sonra 
perfmon yazmamız yeterlidir.





























İlk açılışta Sistem özetiyle birlikte bir açıklama kısmı karşılıyor bizi. Sağ tarafta gördüğünüz gibi İzleme Araçları sekmesinin altında Performans İzleyicisi kısmına basarak buradan olayımıza göre istediğimiz sayaçları ekleyip anlık izlemeler yapabilmekteyiz.























Burda Microsoft'un bize sunduğu sayaçlar harici yüklenen programların da kendine özgü sayaçları olabilmektedir. Örnek verecek  olursak SQL Server'ı yüklediğimizde sayaçlara SQL Server'ın çeşitli sayaçları eklenmektedir.























Tekrar sağdaki sekmelere gelecek olursak; İzleme Araçları kısmının altında Veri Toplama Kümeleri sekmesini görüyoruz.Data Collector Sets

Data collector setler kullanıcı tanımlı ve sistem olmak üzere ikiye ayrılmıştır. Sistem üzerinde tanımlı birçok yapılandırma dosyaları bulunmakla beraber bir performance counter görmekteyiz. Performans counter içinde birden çok sayaç barındırarak çalıştırıldığında bizlere bir rapor tutmaktadır. Eğer biz kendi senaryomuza uygun bir performance counter oluşturmak istiyorsak; bunu kullanıcı tanımlı kısmından yeni bir performance counter oluşturabilir ve bunu senaryomuza uygun programlayabilmekteyiz. Bu counterlarla  ilgili raporları da Raporlar sekmesi altında görebiliriz.


Keyifli okumalar..



Konu ile alakalı videom:






6 Şubat 2017 Pazartesi

Kullanıcı Tanımlı Fonksiyonlar

Merhaba arkadaşlar,

Bugün sizlere SQL Server üzerinde kullanıcı tanımlı fonksiyonlardan bahsedeceğim.

Fonksiyonlar SQL Server'da işimizi kolaylaştırmak için ve sürekli tekrar eden querylere kolaylıkla erişim sağlamamız için yaratılan nesnelerdir. Fonksiyonlara SQL Server'da programmability altındaki functions kısmından ulaşabiliriz.





















SQL Server'da yerleşik olarak tanımlanmış, işimiz kolaylaştıran fonksiyonlar vardır.
Örnek vermek gerekirse; getdate() sistem fonksiyonu kullanarak o anın tarih ve saat değerini alabilmekteyiz. Fakat biz bu daha önceden belirlenmiş fonksiyonlar haricinde, kendi amacımız doğrultusunda fonksiyonlar tanımlamak istersek ne yaparız?

Kullanıcı Tanımlı Fonksiyonlar


SQL Server 2000 ile hayatımıza giren kullanıcı tanımlı fonksiyonlar sayesinde yerleşik fonksiyonlar haricinde kendimiz fonksiyon yaratabilmekteyiz. Bu fonksiyonlar 2 ana alt başlıkta toplanmaktadır.

  • Scalar Valued Functions
  • Table Valued Functions


Scalar Valued Functions


Skaler fonksiyonlar bize tek bir değer döndürmektedir. Örnek vermek gerekirse getdate() sistem fonksiyonu bir skaler fonksiyondur. Çünkü çalıştırıldığında, bize tarih ve saat olmak üzere tek bir değer döndürmektedir.

Scalar Function SYNAX

create function fonksiyonadı(parametreler)
returns geri_dönüş_tipi
as 
begin
sql sorguları
return geri_dönüs_degeri
end

Örnek vermemiz gerekirse;
 Dışarıdan alınan iki sayıyı toplayıp bize geri döndüren bir scalar fonksiyon tanımlayalım.








Table Valued Functions


Skaler fonksiyonlardan tek farkı geriye tablo döndürmesidir. Viewlerle benzerlik gösterirler ancak dışarıdan parametre alabilmektedirler.Biz table valued functionsları  from deyiminden sonra da referans tablo olarak kullanabilmekteyiz. Table Valued Functions kendi içerisinde ikiye ayrılmaktadır. Bunlar;
  • Inline TVFs
  • Multi Statement TVFs

Inline TVFs

Geriye tablo döndürebilen ve kompleks olmayan işlemler için kullanılan fonksiyonlardır.

Inline TVF Syntax:

create function fonksiyonadı(parametreler)
returns table
as 
return select ifadesi

Örnek vermek gerekirse;
AdventuresWork2014 üzerindeki production.product tablosu üzerinde dışarıdan girilen productid'ye göre ürünleri listeleyen bir inline tvf oluşturalım.





Çalıştırıldığında çıktımız şu şekilde olacaktır.








Multi Statement TVFs


View ve Stored Procedure birleşimi olarak düşünülebilir. Daha compleks işlemler yapmak için kullanılır. Multi Statement TVF oluştururken returns deyiminden sonra kendimiz bir tablo yaratarak manuel olarak bu tabloya insert işlemi yapıp tablomuzu oluşturmaktayız.

Multi Statement TVFs Syntax:

create function fonksiyonadı(parametreler)
returns @tabloadı(parametreler)
(
@tablo tanımlamaları
)
as 
begin
tabloyu oluşturan işlemler
return 
end

Örnek vermemiz gerekirse;

AdventuresWork2014 üzerindeki person.person tablosu üzerinde dışarıdan girilen full ve last string ifadelerine  göre kişileri uzun ve kısa adlarıyla listeleyen bir multi statement tvf oluşturalım.



















select * from getinfo('full') komutunu çalıştırdığımızda;





select * from getinfo('last') komutunu çalıştırdığımızda;



olarak tablomuz karşımıza gelecekti.

TVF ve Stored Procedure Arasındaki Farklar


TVF ve stored procedure'ler birbirlerine karıştırılmaktadır. Bunlar arasındaki önemli farklara bakacak olursak

  • Fonksiyonlar geriye bir değer veya tablo döndürmek zorundadır.
  • Fonksiyonlar select deyimi ile kullanılırlar. Stored procedure Execute/exec komutları ile çalıştırılırlar.
  • Fonksiyonlar join yapısı içerisinde kullanılabilirken sp'ler join içerisinde kullanılamaz.
  • Bir fonksiyon stored procedure çalıştıramaz fakat stored procedure'ler fonksiyonları çalıştırarak bu fonksiyonlardan faydalanabilmektedirler.
  • Fonksiyonlar transaction yapısını desteklemezler.
  • Fonksiyonlar tablo türü değişkenlerle kullanılabilirler(temp table hariç), Stored procedure'ler hem temp table hem de tablo türü değişkenlerle kullanılabilirler.
  • Fonksiyonlar try-catch yapısını desteklememektedir. 



Konu ile ilgili video:



ek zorundadır.


28 Ocak 2017 Cumartesi

Constraint Kullanarak Veri Bütünlüğü Sağlamak

Merhaba arkadaşlar,

Bu yazımda sizlere veri bütünlüğünün ne olduğunu ve kısıtlayıcı(constraint) kullanarak veri bütünlüğünü nasıl sağladığımızdan bahsetmek istiyorum.

Veri Bütünlüğü Nedir?


Veri bütünlüğünü, ilişkisel veri tabanlarında yanlış verilerin girişini önlemek, tablolara yaptığımız insert, delete ve update işlemlerinde verilerin ilişkili tablolarla uyumluluğunu ve veri bütünlüğünü sağlamak için yapmaktayız.Örnek vermek gerekirse;

Şirket çalışanlarının bilgilerinin tutulduğu bir tablo düşünelim. Bu tabloda;

  • ÇalışanID sütununa girilen verilerin benzersiz olması
  • Çalışan isim ve soyadlarının 12 karakterden fazla olmaması
  • DepartmanID'lerin ilişkili başka tablodaki verilerle bütünlüğün sağlanması gibi.


Veri bütünlüğünü sağlarken bazı yöntemlerden faydalanmaktayız. Bu yöntemler; constraint, rule ve default, trigger, stored procedure ve sql server dışından veri bütünlemesi yapmak için kullanılan programlama dillerinden oluşmaktadır. Bu yöntemler iki ana başlıkta toplanmaktadır.

  • Tanımlanabilir Veri Bütünlüğü
  • Prosedürel Veri Bütünlüğü


Yukarıdaki resimde görüldüğü üzere yukarıdan aşağıya doğru giderken fonsiyonellik artarken performansta bir düşüş yaşanmaktadır.

Bu yöntemleri seçerken dikkat etmemiz gereken nokta:

Her zaman çözümü en alt katmanda çözmeye çalışmalı, eğer çözülemiyorsa bir üst katmana giderek çözüm aramalıyız.

Bunun nedeni üst katmanlara çıkıldıkça SQL Server'a daha fazla yükün binmesi.

Örnek vermek gerekirse;

Veri bütünlüğünü constraint kullanarak halledebilecek iken trigger kullanmak.

Trigger'lar constraintlerin aksine transaction sonrası devreye girerler. Yani veriler üzerinde bozulma olup olmadığını işlem bittikten sonra kontrol ederler. Eğer veri bütünlüğünde bir bozukluk yoksa hiçbir sorun olmayacaktır. Fakat veri bütünlüğünde bir sıkıntı varsa transaction sonrası bunun için SQL Server'a ekstra bir iş yükleneceğinden gereksiz bir performans kaybına neden olabiliriz.

Tanımlanabilir Veri Bütünlüğü

Constraint'ler rule ve default'lardan oluşan ve oluşturulan nesneleri kullanarak sağlanan veri bütünlüğüdür. Kullanımın basit olması açısından avantajlı olmakla beraber dışarıdan fazla müdahele edilememesi açısındna dezavantajıdır.

Tanımlanabilir veri bütünlüğü 3 esasa dayanmaktadır.

Varlık(Entity) Bütünlüğü


Bir tabloya girilen her farklı satır için bir ayırıcı olmasını sağlamaktadır.(primary key)

Alan(Domain) Bütünlüğü


Tablodaki sütunların hangi değerleri alabileceği, bu sütunların null değer alıp alamayacağını sağlamaktadır.

Referanssal(Referential) Bütünlük


Primary ve foreign key kullanarak birbirine bağlı tablolardan foreign keyli tablo üzerinde silinmeyen tek bir kayıt dahi olduğu sürece ana tablo üzerinden silme işleminin yapılamayacağını garanti eder. Yani bir anne kaydı silmek için bu kayda ait bütün çocuk kayıtları silmek gerekmektedir.


Constraint

Kelime anlama kısıtlama olan constraintler, veri üzerinde mantıksal sınırlama yapmak için kullanılmaktadır. Constraintler tablo tanımlanırken veya tablo tanımlandıktan sonra oluşturulabilmektedir. Rule ve Default'ların constraint'lerden farkı tablo dışında ayrı bir nesne olarak tanımlanmasıdır. Rule ve Default'un yaptığı her işlemi constraint kullanarak yapabilmekteyiz. SQL Server'ın Rule ve Default'a hala destek vermesinin geriye dönük uyumdan dolayıdır. Rule'un yaptığı işi check constraint, Default'un yaptığı işi default constraintle yapabiliriz.

Primary Key Constraint

  • Birincil anahtar kısıtlayıcısıdır.
  • Null değer alamaz
  • Aynı olmayan değerlerin girilmesini sağlar.
Örnek vermek gerekirse;
musterid sütununa primary key constraint tanımlamak istersek

Constraint pk_musterid primary key (musterid)

Unique Constraint

  • Tekil anahtar kısıtlayıcısıdır.
  • Tablodaki sütunlara unique değer girmek için kullanılır.
  • Boş değer alabilir ve tablodaki birden fazla sütunda kullanılabilir.
Örnek vermek gerekirse;
tcno sütununa unique key constraint tanımlamak istersek

Constraint uq_tcno unique (tcno)

Foreign Key Constraint

  • Yabancıl anahtar kısıtlayıcısıdır.
  • Bir tablodaki bir sütuna ait verilerin başka bir tablonun  belirli bir sütunundan gelmesini denetler.
Constraint fk_musterid foreign key (musterid) references tablo1(musterid)

Delete Update işlemleriyle Foreign Key Kullanımı

İlişkili tablolar üzerinde delete update işlemi yaparken bağlı tablo üzerinde de bazı işlemlerin geçerli olmasını isteyebiliriz. Bunun için aşağıdaki deyimleri kullanmaktayız.

CASCADE: Foreign key tanımlı tabloya aynı aksiyonu uygular.
SET NULL: Foreign key kolonlarını null değerlerine ayarlar.
SET DEFAULT: Foreign key kolonlarını default değerine ayarlar.

Constraint fk_musterid foreign key (musterid) references tablo1(musterid) on delete [castade|set null|set default] on update [castade|set null|set default]  

Default Constraint

  • Bir sütuna önceden belirlenmiş bir değer atamak için kullanılır.
  • insert işleminde geçerlidir.
Örnek vermek gerekirse; tarih bilgisi girilmediğinde tarih sütununa getdate() fonksiyonuyla tarih sütununa veri girişi yapmak istiyoruz.

Constraint df_tarih default (getdate()) for tarih

Check Constraint

  • Kontrol kısıtlayıcısıdır.
  • Belirlenen formata göre veri girişi yapmak için kullanılır.
Örnek vermek gerekirse; numara sütununa 100 rakamından büyük değerlerin girmesini istediğimizde

Constraint chck_no check (numara>100)


Bu constraintleri silmek istersek bunu drop komutuyla yapmaktayız.

drop constraint contraint_ismi

 sp_helpconstraint tablo_adı stored prosedürünü kullanarak tablo üzerindeki tanımlanan kısıtlayıcıları listelemek mümkündür.

Konu ile alakalı videom:




22 Ocak 2017 Pazar

Improving Query Performance

Herkese merhaba,

Bugün sizlerle, SQL'de yazdığımız sorgularımızın performansı ile ilgili çektiğim videoyu paylaşmak istiyorum.
Çekmiş olduğum videomda;

  • Sorgu yazarken performans açısından neler yapabiliriz, nelere dikkat etmeliyiz.
  • Database engine bir sorguyu çalıştırırken nasıl bir yöntem izlemektedir.
  • Yazılan sorguların performans takibini nasıl yapmaktayız. 

gibi konuları ele aldım.

 Konu ile ilgili videom:



Görüşmek üzere, kendinize iyi bakın.

12 Ocak 2017 Perşembe

Set Operators

Herkese merhaba,

Bugün sizlere  veritabanımızda kullandığımız set operatörlerinden bahsedeceğim.

Set operatörleri iki veya daha fazla sorguyu kümelemek için kullanılmaktadır.

Bu set operatörlerini kullanarak birleştirdiğimiz sorgulara bileşik sorgu yani compound queries denmektedir.

Sorgularımız arasındaki çeşitli işlemler için farklı set operatörleri vardır.
Bunlar;

  • UNION, UNIONALL
  • EXCEPT, INTERSECT
  • APPLY, CROSS APPLY, OUTER APPLY
UNION ve UNION ALL Set Operatörleri

Bu operatör iki veya daha fazla sorguyu tek bir tablo olarak bize geri döndürür. 

Bu operatörleri kullanırken dikkat etmemiz gereken önemli bir nokta var:

Karşılaştırma yaptığımız iki sorgu arasındaki ifadelerin türleri aynı olmalıdır.
Yani bir tablonun nvarchar türündeki bir sütunuyla diğer tablonun int türündeki bir sütunu birleştirip tek bir tablo olarak geri döndüremeyiz.

UNION operatörü karşılaştırılan ifadeleri getirirken DISTINCT komutuyla aynı işlemi yaparak tekrar eden ifadeleri bize geri döndürmezler. Eğer bu ifadeleri de görmek istiyorsak UNION ALL deyimini kullanmalıyız.

Union Syntax:

<query_specification>
UNION [ALL]
<query_specification>


 Örnek vermemiz gerekirse;
Bir şirketin içerisindeki çalışanlar veritabanımızda çalıştıkları departman tablolarında ayrı ayrı tutuluyor olsun. Bu departman tablolarını Departman1 ve Departman2 olarak isimlendirelim.

Biz bu şirket çalışanlarını bir tablo altında listelemek istediğimizde UNION operatörünü şu şekilde kullanıyoruz.

select Name as Calısanlar from Departman1 
UNION
select Name from Departman2

Bu iki sorguyu UNION operatörüyle birleştirip tek bir tabloda Calısanlar adlı sütunun altında şirket çalışanlarını listelemiş olduk.

EXCEPT, INTERSECT

Except ve Intersect operatörleri belli kurallara göre iki sorgu arasında karşılaştırma yapmak için kullanılmaktadır.

Except Operatörü: İki sorgu arasında karşılaştırma yaparken, ilk sorgudaki tabloda yer alan fakat ikinci sorgudaki tabloda yer almayan ifadeleri bize geri döndürür. Yani tablolar arasındaki farkı görmek istediğimizde Except operatörünü kullanmamız gerekmektedir.

Except Syntax:

<query_specification>
EXCEPT
<query_specification>

Intersect Syntax:

<query_specification>
INTERSECT
<query_specification>

Örnek vermek gerekirse;

Müşterilerimiz ve bu müşterilerimizin siparişlerinin tutulduğu iki ayrı tablomuz olsun. Biz bu iki tabloyu karşılaştırarak sipariş vermemiş müşterilerimizi tek bir tabloda  EXCEPT operatörünü kullanarak görüntüleyebiliriz.

select CustomerID from Sales.Customer
EXCEPT 
select CustomerID from Sales.SalesOrderHeader

Except operatörünü kullanarak iki tablo arasındaki CustomerID'leri karşılaştırdık ve Customer tablosunda olup SalesOrderHeader tablosunda olmayan CustmerID'leri listeledik. Yani sipariş vermemiş müşteriler listelendi.

Intersect Operatörü: İki sorgu arasında karşılaştırma yaparken, karşılaştırdığımız ifadelerin iki tablodada mevcut olması durumundaki verileri bize tek bir tabloda geri döndürür. Bir önceki örnek üzerinden açıklayacak olursak;

select CustomerID from Sales.Customer
INTERSECT 
select CustomerID from Sales.SalesOrderHeader

Bu operatörü kullanarak iki tabloda da var olan CustomerID 'leri listeledik. Bu durumda listelenen CustomerID 'ler aynı zamanda sipariş veren müşterileri belirtmektedir.

APPLY, CROSS APPLY, OUTER APPLY

SQL 2005 ile birlikte gelmiş olan APPLY operatörü tvf'lerle join işlemi yapar. Yani biz bu operatörle

Tablomuzdaki veriyi fonksiyon içerisine parametre olarak gönderir ve belli kurallara göre verilerimizi listeleriz. 

Belli kurallar dediğimiz deyimler CROSS  ve OUTER deyimleridir.

CROSS APPLY ile sadece fonkisyondaki değerlerle uyuşan satırlar bize geri döndürülmektedir. Bunu Join işlemi gibi düşünebiliriz. Fakat Join işlemiyle fonksiyonlar içerisine parametre gönderemezken APPLY operatörleriyle parametre gönderebilmekteyiz.
OUTER APPLY ise fonksiyondaki değerlere uyuşup uyuşmadığına bakmaksızın join edeceğimiz tablodaki değerleri bize geri döndürücekti. (Bunu bir nevi left join işlemi gibi düşünebiliriz)

Bir örnek vermek gerekirse;

Müşterilerimizin ve Siparişlerinin tutulduğu iki tablomuz olduğunu varsayalım. Biz dışarıdan girilecek müşteri id'sine göre müşterilerimizin siparişlerini listeleyen bir fonksiyon yazalım ve CROSS APPLY operatörüyle müşteri tablomuzu fonksiyonla birleştirelim.

CREATE FUNCTION  getorder
(
@custid as int, @n as int
)
RETURNS TABLE
AS 
RETURN
Select top (@n) * From Sales.SalesOrderHeader 
WHERE CustomerID=@custid
ORDER BY TotalDue Desc
GO

Select c.CustomerID,o.TotalDue from Sales.Customer as c
CROSS APPLY
getorder(c.CustomerID,5) as o ORDER BY CustomerID ASC,TotalDue DESC

Gördüğünüz gibi CROSS APPLY ile sadece fonksiyon içerisinde eşleşen CustomerID'lerin en yüksek 5 siparişini listelemiş olduk.

Eğer CROSS APPLY yerine OUTER APPLY  operatörünü kullansaydık fonksiyon içerisinde eşleşmeyen CustomerID'leri de listeleyecektik.






Konu ile ilgili Sunumum:












5 Ocak 2017 Perşembe

Writing Simple Case Expressions

Merhaba arkadaşlar,

Bugün sizlere Case Expressions hakkında çektiğim videoyu paylaşacağım. 

Bu videonun içeriğinde CASE yapısını, nasıl ve ne için kullanıldığını örneklerle anlatmaya çalıştım.







Görüşmek üzere, kendinize iyi bakın.