Makale Özeti

Sql Server ile yeni yeni haşir neşir olmaya başlayan yada en azında Sql Server ile programlama yapmayıp sadece tablolar ve view ler yaratmış okuyucular için bu konu başlığı biraz karmaşık gelebilir. Zira bana göre Sql Server kullanabilen birkaç grup developer var. Bunların bir bölümü sadece tablolar yaratıp ASP,VB,Delphi,C# gibi programlama dilleri yardımıyla ve ilgili dilin kendi içindeki kaynakları kullanarak(recordset, dataset,vs) sql sorgularını çalıştırmakta ve o anlık ihtiyaçlarını karşılamaktalar. Bir diğer kesim ise işin sorgu yönetimi ve karmaşık sorgular kısmını Sql Server içinde yer alan Stored Procedure, View, Trigger, vs tool ve yöntemler ile halledip hem kullandıkları programlama dilinde karmaşık ve uzun kodlar yazmaktan kurtuluyor hemde ciddi bir performans artışı sağlıyorlar.

Makale

Sql Server ile yeni yeni haşir neşir olmaya başlayan yada en azında Sql Server ile programlama yapmayıp sadece tablolar ve view ler yaratmış okuyucular için bu konu başlığı biraz karmaşık gelebilir.

Zira bana göre Sql Server kullanabilen birkaç grup developer var. Bunların bir bölümü sadece tablolar yaratıp ASP,VB,Delphi,C# gibi programlama dilleri yardımıyla ve ilgili dilin kendi içindeki kaynakları kullanarak(recordset, dataset,vs) sql sorgularını çalıştırmakta ve o anlık ihtiyaçlarını karşılamaktalar. Bir diğer kesim ise işin sorgu yönetimi ve karmaşık sorgular kısmını Sql Server içinde yer alan Stored Procedure, View, Trigger, vs tool ve yöntemler ile halledip hem kullandıkları programlama dilinde karmaşık ve uzun kodlar yazmaktan kurtuluyor hemde ciddi bir performans artışı sağlıyorlar.

Ben bu yazıda Sql Serverı daha etkin kullanmak isteyen kesime hitaben basit örnekler üzerinden "Cursor" yapısını anlatmaya çalışacağım.

Cursor, T-SQL programlama ile Sql Server içinde yaratacağınız temporary bir result set üzerinde navigasyon yapmanıza olanak tanır. Nedir bu cümleden kastımız: Cursor sayesinde Select sorgusu çektiğiniz bir tablodan dönen resultset içinde ileri-geri navigasyon yapabilmeniz. Aslında özet bir cümleyle Cursoru pointerlara benzetebiliriz.

Sql Serverda cursor talep etmek için (request) iki yöntem vardır:
- T-SQL
- API fonksiyonları

Sql Server aşağıdaki Database Application Interface(Database Uygulama Arayüzü) ve Object Interface(Nesne Arayüzü) destekler:
- ADO (ActiveX Data Objects)
- OLE DB
- ODBC (Open Database Connectivity)
- DB Library

Önemli :
Cursor kullanarak çalışmada belki de en çok dikkat etmemiz gereken konu Cursorun bellekte kapladığı yer konusudur. Zira Cursor bellekte ciddi bir yer kaplar. Bu kimi zaman virtual memory, kimi zaman temp memory, kimi zaman bir database olacaktır. Bu nedenledir ki Cursor kullanımında gereksiz kullanımlardan kaçınılmalı ve işi biten Cursor nesnesi kapatılıp yok edilmelidir. Bu kural çerçevesinde kaldığınız sürece Cursoru çalışmalarınızda ciddi performans kayıpları ile karşılaşmadan kullanabilirsiniz.

Cursorun Çalışma Şekli

Şimdi adımlar halinde cursor yaratma, kullanma ve yok etme aşamalarına değinelim:

- Cursor tanımlanır

DECLARE <Cursor_Adi> CURSOR

Cursor bir Select statement barındırır. Daha doğrusu bir resultset döndürmesi gerekir.

- Cursoru çalıştırmak ve bir resultset döndürmesini sağlamak için "Open" komutu kullanılır.

Open <Cursor_Adi>

- ResultSetin sonuna gelene dek her seferinde bir satırı işleme almak için "fetch next" komutu kullanılır.

- Cursor kapatılır ve yok edilir (Close - Deallocate)


Sql Serverın kendi tablolarını kullanarak bir örnek verelim :

Örneğimiz Northwind databaseinde bulunan tablo isimlerini alsın ve özelliklerini grup halinde listelesin :
 
USE Northwind
DECLARE test_cursor CURSOR
     FOR
     SELECT name FROM sysobjects
          WHERE type = U ORDER BY name
OPEN test_cursor
DECLARE @tablo_ismi sysname
FETCH NEXT FROM tbl_space INTO @tablo_ismi
WHILE (@@FETCH_STATUS = 0)
     BEGIN
        EXEC sp_spaceused @tablo_ismi
        FETCH NEXT FROM test_cursor INTO @tablo_ismi
     END
CLOSE test_cursor
DEALLOCATE test_cursor


Burada yaptığımız sysobjects fonksiyonu ile oluşturduğumuz resultset içinde tablo isimlerini cursor yardımıyla ilkten-sona tek tek sp_spaceused stored procedureune parametre olarak göndermek ve dönen sonucu ekrana yazdırmak. Sona geldiğimizi anlamak için

WHILE (@@FETCH_STATUS = 0)

satırı ile anlayabiliyoruz.

Bu şekilde hazırlanmış bir querynin sonucu :



şeklinde olacaktır.

Şon olarak Cursor Syntaxına bakmamız gerekirse bazı terimleride açıklığa kavuşturmuş oluruz sanırım:
 

Deyim Açıklama
DECLARE CURSOR Cursor yapısını oluturur ve kullanımı için bellekte yer açar
OPEN Declare edilmiş cursor u kullanıma açar
FETCH Cursorun oluşturduğu resultset te navigasyon (ileri-geri) hareket sağlar
CLOSE Cursor kapatılır
DEALLOCATE Cursor sistemden silinir ve kullanılan bellek açığa kavuşur

Cursor kullanımı esnasında output verebilen birçok fonksiyon kullanılır. Örnek vermek gerekirse en çok kullanılanlar arasında :

@@Fetch_Status = Açık bağlantı ve cursor yapısı içinde bulunulan pozisyonun son kayıta göre konumunu belirtir. Bunu bir For döngüsüne benzetmek mümkündür. Örneğin
WHILE (@@FETCH_STATUS = 0) deyimiyle son kayıtta olmamız durumundan bahsedilmektedir.

@@Cursor_Rows = Mevcut bağlantı içinde son açılan cursor un resultsetinde yer alan kayıt sayısını verir.

Cursor_Status = Bir Stored Procedure çalıştırdığınızda size output değeri vermek için bir cursor hazırlar. Bu tag sayesinde hazırlanan cursor un durumu hakkında bilgi alınabilir.


Evren AYAN
www.evrenayan.net