25 Haziran 2011 Cumartesi

Sql Recursive Functions(Rekürsif Fonksiyonlar)

Recursive fonksiyonlar, kendi kendini çağıran fonksiyonlardır. C#'ta da vardır, Java'da da , C'de de. Basit bir mantık, kendi işlemini yaptıktan sonra, tekrar kendi fonksiyonunu çağırması ve tekrar kendi içinde bulunan işlemleri tekrarlamasıdır. Sql'de de böyle bir işleme ihtiyacımız olabilir. Örneğin, bir kategori kendi içinde alt kategorileri olsun, o alt kategorilerin de altında başka kategoriler daha olsun. Gördüğünüz gibi, bir hiyerarşi oluşmuş. Biz sadece bir taban altına gitmemiz, doğru bir yaklaşım olmayacaktır. En alt katmana gelene kadar, kendi kendini sürekli çağırmalı ve gerekli işlemler yapılmalıdır.

Recursive fonksiyonlara verilebilecek en klasik örnek, faktöriyel hesabıdır. 5! dediğimiz zaman, önce 5 diyecek, daha sonra kendini çağırıp 5.4 olacak, daha sonra yine kendini çağırıp 5.4.3 diye diye 0 olana kadar bu kendini çağırma işlemi devam edecek.

Benzer senaryo, Sql'de de karşımıza gelebilir. Örneğin, AdventureWorks veritabanı üzerinde, HumanResources.Employee tablosunda, id'si 4 olan personelin bağlı olduğu şef, o şefin bağlı olduğu diğer şef, o şefin bağlı olduğu diğer şef ... vs. Genel Müdür gelene kadar bu işlem devam etmesini istiyorsak, gördüğünüz üzere bu hiyerarşik yapıyı kullanmak için recursive fonksiyon yazmamız gerekir. Kodlama aşağıdaki gibi olmalıdır;


with CTE as
(
      select EmployeeID,ManagerID,Title from HumanResources.Employee
      where EmployeeID=4 --baslangic id
      union all
      select HE.EmployeeID,HE.ManagerID,HE.Title from HumanResources.Employee HE join CTE
      on HE.EmployeeID=CTE.ManagerID
)

select * from CTE

Sonuç kümesi de aşağıdaki gibi olur;



Kodlama hakkında bilgi vermek gerekirse, öncelikle CommonTableExpression yazmamız gerekir. Bunu herhangi bir yazılım dilindeki fonksiyonlara benzetebilirsiniz. Orada o fonksiyonu sürekli çağırırken, burada da sürekli CTE ile joinlediğimiz zaman, sürekli bir üst katmana gittiğini göreceğiz. Rekürsif fonksiyonlar, ikinci sorgumuz -CTE ile join yaptığımız- boş sonuç verene kadar devam eder. Ama bu işlem ciddi performans kayıplarına yol açmaması için, Sql Server default'u olarak 100 verilmiş. Yani en fazla 100 kez bu işlem devam edecektir. Ama biz en fazla kaç kere dönmesini de değiştirebiliriz. Bunun için yazmamız gereken kod, Select * from CTE'nin sonuna 

OPTION(MAXRECURSION 4)

yazmak olmalıdır.


2 yorum:

Adsız dedi ki...

Teşekkürler , çok güzel olmuş lakin database i de ekleseydiniz daha güzel olacaktı. Yinede teşekkürler.

Adsız dedi ki...

Harika bir anlatım, paylaşım için teşekkürler.