15 Kasım 2015 Pazar

SQL Cursor (İmleç) Kullanımı

Fetch,İmleç,Cursor vs...

SQL Server’daki imleç (cursor), bir metin editöründeki imleçlerle aynı görevi yapar. Metin editöründe çalışma anında, imleç nerede bulunuyorsa oradaki verileri temel alan işlemler yapılabilir. SQL Server’daysa imlecin bulunduğu yerdeki verilere satır satır erişilebilir. Veritabanı ortamında bir seçme sorgusu sonucu erişilen kayıtlara bir döngü çerçevesinde tek tek erişim sağlayabilmek için imleç programlamak gerekir. İmleçler, veritabanlarında saklanmaz.
İmleçler performans açısından çok tercih edilmemektedir. Bu yüzden gerekmedikçe imleç kullanılmamalıdır. CASE yapısı ya da geçici tablolar kullanarak imleç kullanmadan aynı sonuçlar elde edilebilmektedir. İmleçler, satır satır hareket etmenize olanak sağlayarak kimi zaman işinizi çok kolaylaştırsalar da çoğu zaman performans kaybına sebep olurlar. Bu yüzden, gereksiz yere imleç kullanmaya çalışmayınız.

Kullanım Amaçları

İmleçler;
  •  Bir sonuç setinde o anda bulunulan pozisyondaki satır veya takip eden satırlardaki verilere ulaşmak,
  •  Yapılan bir sorgu sonucu geri dönen değerlerden her satırı ayrı ayrı değerlendirip duruma göre verileri değiştirmek,
  •  Tetikleyici (trigger) veya Stored Procedure’lerin bir sonuç setine satır satır ulaşmasını sağlamak,
  •  Diğer kullanıcılar tarafından yapılan değişikliklerin görünebilirlik seviyesini ortak zamanlı çalışmada ayarlamak için kullanılırlar.

T-SQL İmleçler

T-SQL imleçler sunucu tarafından çalışır ve sadece bir sonuç seti (resultset) üzerinde tanımlanırlar. Bu şekilde tanımlanan bir imleçte, kayıt seçmek için yazılan SELECT sorgusunda COMPUTE, COMPUTE BY, INTO deyimleri bulunmaz.

T-SQL Cursor Kullanımı

Beş adımdan oluşur:
  • İmleç değişken tanımlama: Bir SELECT ifadesinde, bir değişken tanımlanarak seçme işlemi sonucunda elde edilecek değeri tutacak imleç tanımlanmış olur.
  • İmleci açma: SELECT işleminden sonra imleç ilk satırı işaret edecek şekilde ayarlanır.
  • Erişim ile ilgili işlemler: FETCH deyimi kullanılarak, bir döngüyle satırlara erişilir. Değişiklik ve okuma yapılabilir.
  • İmleci kapatma: CLOSE deyimiyle imleç kapatılır. Tekrar açılabilir.
  • İmleci bellekten silme: DEALLOCATE deyimi imleci bellekten siler.

@@FETCH_STATUS ve @@ROWCOUNT

Yapılan işlemler sonucunda imlecin son satıra gelip gelmediğini anlamak için @@FETCH_STATUS ve @@ROWCOUNT fonksiyonları kullanılır.
FETCH_STATUS fonksiyonu, en son çalıştırılan FETCH komutunun sonucu hakkında bilgi verir.
FETCH_STATUS fonksiyonu üç farklı değer alabilir.
Değer Açıklama
0 Bir önceki FETCH komutu başarıyla gerçekleştirildi.
-1 Bir önceki FETCH komutunda hata ile karşılaşıldı.
2 Son kayıta ulaşıldı. (end of resultset)
Tablo 1: @@FETCH_STATUS fonksiyonu değer tablosu
@@ROWCOUNT fonksiyonu, bir önceki FETCH komutu başarıyla gerçekleştirildikten sonra sonuç setinde toplam kaç kaydın bulunduğunu tutan fonksiyondur. FETCH komutu hiç kullanılmamışsa, imlecin işaretlediği sonuç setinde toplam kaç kaydın yer aldığını gösterir.
Örnek
Kitaplar tablosunun istenilen içeriğini yazdıracak bir imleç tanımlayıp kullanacağınızı varsayınız.
Resim 1: Kitaplar tablosu
  • İlk adımda imleç tanımlanır.


Resim 2: İmlecin tanımlanması ve SELECT sorgusu

  • İkinci adımda imleç açılır.
Resim 3: İmlecin açılması
  • Üçüncü adımda imleç üzerinde dolaşmak için FETCH komutundan faydalanılır. Bu sorgu tarafından döndürülen iki satıra karşılık değişkenler tanımlanır. FETCH ile ilk satırın üstüne gelinir ve ilk kayıtta yer alan iki değer yazdırılır.



Resim 4: FETCH komutunun kullanılması
  • İmleç kapatılır.


Resim 5: İmlecin kapatılması
  • Gerekirse hafızadan silinir.


Resim 6: İmlecin hafızadan silinmesi

  • Eğer, birden fazla kayıt yazdırılacaksa döngü kullanılmalıdır.
Resim 7: Birden fazla kayıt için döngü kullanılması


 Resim 8: İmleç oluşturma ve kapatma işleminin tamamı

CAST fonksiyonuyla int tipindeki @KitapKod değişkeni VARCHAR tipine dönüştürülmektedir. Sorguyu çalıştırdıktan sonra elde edilen sonuçları Messages penceresinden görebilirsiniz.

  Resim 9: İmlecin sonucu

 İmleç Seçeneklerini Ayarlamak

Bir imlecin tipi ve davranışı ayarlanabilir.
  • CursorType: Forward-Only, static, keyset-driven, dynamic değerlerinden birini alabilir. Genel olarak istemci tipi imleçler, forward-only’dir. ODBC, OLE DB veya DB-Library gibi API’ler tarafından bu değer otomatik olarak ayarlanabilir. Kullanıcının istediği şekle de getirilebilir.
  • CursorBehaviors: SCROLL ve INTENSIVE tiplerinden birini alabilir. ODBC ve DB-Libraray bu özellik için değer ataması yapmaz.

İmleçlerle Satırlar Arasında Dolaşmak

Bir imleç satırlar üzerinde dört temel işlevi yerine getirir: İlk kayıta, son kayıta, önceki veya sonraki kayıta gidebilir ve SCROLL CURSOR olarak adlandırılırlar.
İfade İşlevi
FETCH FIRST İlk satıra konumlanır.
FETCH LAST Son satıra konumlanır.
FETCH NEXT Bir sonraki satıra konumlanır.
FETCH PRIOR Bir önceki satıra konumlanır.
FETCH RELATIVE n Bulunulan satırdan n kayıt ileriye konumlanır.
FETCH ABSOLUTE Baştan n. kayıta konumlanır.
Örnek Tablo 2: Hareket ifadeleri
“Kitaplar” tablosu üzerinde imleci çeşitli şekillerde hareket ettireceğinizi varsayınız.



Resim 10: FETCH komutu ile satırlar arasında dolaşım örneği

Bu Query’i çalıştırdığınızda elde edilen sonuçları Results penceresinden görebilirsiniz.




Resim 11: Sonuç penceresi

İmleçle Kayıtları Düzenlemek

Bir imleçle, üzerinde bulunulan satırı silebilir veya düzenlemeler yapabilirsiniz. Bu işlemler aslında UPDATE ve DELETE komutlarıyla da yapılabilir ancak bir UPDATE veya DELETE ifadesiyle ifade edemeyeceğiniz bir işlem karşınıza gelirse bu tür bir yöntemi tercih edebilirsiniz.
UPDATE ve DELETE ifadelerinin WHERE kısmı için WHERE CURRENT OF ifadesini kullanabilirsiniz.


Resim 12: WHERE CURRENT OF ifadesi


Ortak Zamanlı Çalışma

İmleçlerle bir veriye erişirken aynı anda başka başka kullanıcıların da bu veriye erişimlerini düzenlemek için kilitleme mekanizması devreye konulabilir.
Bir imlecin verilere ortak erişiminin düzenlenmesi için iki yöntemden biri kullanılabilir. Oturum seviyesinde kilitleme seçeneğini tayin ederek imleç veriye eriştiği anda diğer erişim isteklerinin hangi haklara sahip olacağı otomatik olarak tayin edilebilir. İmleci tanımlayan FROM cümlesinden sonra kilitleme seçeneği belirtilerek sadece imlecin işi bitinceye kadar olan süre zarfında, aynı kaynaklara erişmek isteyenler için bir kilitleme seçeneği belirtilebilir.
FROM’dan sonra Tablo 3’teki ifadelerden biri gelebilir.

İfade İşlevi
READ_ONLY Pozisyona bağlı güncellemelere izin verilmez ve imleç açıldığında
herhangi bir kilit konmaz.
OPTIMISTIC Hiçbir satırı kilitlemez. Satır bazında değişiklikleri SQL Server
WITH VALUES takip eder.
OPTIMISTIC Timestamp türü sütunu olan bir tablo üzerindeki imleçler için
tanımlanabilir. Bu tür bir imleç, sadece timestamp sütun değerine
WITH ROW
bakarak kendisinden sonra değişip değişmediğini anlamasını
VERSIONING
sağladığı için server açısından daha az yük bindiricidir.
SCROLL LOCKS SELECT cümlesinde verilen kilitleme ipucuna göre kilitleme yapar.
Tablo 3: Ortak zamanlılık seçenekleri
Kaynak: MEGEP

26 Ekim 2015 Pazartesi

Excel'de Seçilen Tüm Metni Büyük Harfe Çevirmek

Excel'de Tüm Seçilenleri Büyük/Küçük/İlk Harfi Büyük Harfe Çevirmek

Excel'de Wordde olduğu gibi seçilen satırdaki verilerin tamamını büyük veya tamamını küçük harfe çevirecek hazır bir tool yoktur.

Bunun yerine aşağıdaki makroları çalışma kitabınıza ekleyip ihtiyacınıza göre ilgili hücrelerde çalıştırmanız işinizi görecektir.


Bir Aralıktaki Tüm Metni Büyük Harflere Dönüştüren Makro


Sub Uppercase()
   ' Belirtilen aralıktaki her bir hücreye tek tek git.
   For Each x In Range("A1:A5")
      ' Aralıktaki metni büyük harflere dönüştür.
      x.Value = UCase(x.value)
   Next
End Sub
    

Bir Aralıktaki Tüm Metni Küçük Harflere Dönüştüren Makro


Sub Lowercase()
   ' Belirtilen aralıktaki her bir hücreye tek tek git.
   For Each x In Range("B1:B5")
      x.Value = LCase(x.Value)
   Next
End Sub
    

Bir Hücre Aralığındaki Tüm Metni İlk Harfleri Büyük Olacak Şekilde Değiştiren Makro


Sub Proper_Case()
   ' Belirtilen aralıktaki her bir hücreye tek tek git.
   For Each x In Range("C1:C5")
      ' Visual Basic for Applications'ta Yazım Düzeni işlevi yoktur.
      ' Bu nedenle, çalışma sayfası işlevini aşağıdaki şekilde kullanmalısınız:
      x.Value = Application.Proper(x.Value)
   Next
End Sub
    


25 Ekim 2015 Pazar

SQL'de Geçici Tablo (Temporary Tables) Kullanımı

Temporary Tables

Veritabanı üzerinde geçici bir süre için ek tablolara ihtiyaç duyulduğunda T-SQL ile geçici tablolar oluşturulup, kullanılır. Geçici tablolar, gerçek tablolar üzerinde işlemler yapmak yerine, farklı sorgulamaların yapılabileceği bir deneme tahtası gibi kullanılır. Yani önemli tablolar üzerinde kritik sorgular çalıştırmak zorunda kalındığında ve sonuçlar tahmin edilemeyecek gibiyse, geçici bir tablo oluşturulur ve kodlar bu geçici tablo üzerinde test edilir; daha sonra istenilen kodlar gerçek tabloya uygulanır. Aynı zamanda geçici tablolar, karmaşık ve çok fazla bilgi olan tablolardan sadece belirli bir kısmı alarak üzerinde çalışmak için de kullanılabilir.
 
 


Geçici tablolar SQL Server’da tmpdb isimli veritabanının altında saklanırlar. Geçici tablolar, yerel geçici tablolar (local temporary tables) ve genel geçici tablolar (global temporary tables) olmak üzere ikiye ayrılırlar. Yerel geçici tablolar, tabloyu oluşturan kişi SQL Server ile olan bağlantısını kapattığında yok edilir. Genel geçici tablo ise son aktif bağlantı kapatıldığı anda yok edilir. Yani geçici tabloyu oluşturan kişi ile birlikte o anda SQL Server’a birden fazla kişi bağlı bulunabilir. Bu durumda tabloyu oluşturan kişi SQL Server ile olan bağlantısını kapattıktan sonra SQL Server’a bağlı bulunan kimse kalmayana kadar geçici tablo saklanır ve bağlı bulunan en son kişi bağlantısını sonlandırdığında tablo silinir.

Geçici tablolar, normal bir tablo oluşturmak için kullanılan "CREATE TABLE" ifadesi ile  oluşturulurlar. Ancak, tablonun geçici olduğunu SQL Server'a bildirmek için tablo adı önüne "#" işareti eklenir. Bu şekilde oluşturulan tablolar yerel geçici tablolardır ve sadece o oturum için geçerli olup, oturum kapatıldığı andan itibaren veya başka bir sorgu (query) ekranından erişilemezler.

CREATE TABLE #Temporary(
     number INT PRIMARY KEY,
     name NVARCHAR(50),
     surname NVARCHAR(50)
)

Geçici tablolara, başka oturumlar üzerinden veya diğer kullanıcılar tarafından erişimi sağlamak için tablolar, "#" yerine "##" (genel geçici tablo) kullanılarak oluşturulmalıdır. 

CREATE TABLE ##GlobalTemporary(
     number INT PRIMARY KEY,
     name NVARCHAR(50),
     surname NVARCHAR(50)
)




Geçici tablolar oluşturmanın iki yöntemi vardır:


1. yöntem: Oturum boyunca geçerli geçici tablolar oluşturmak için kullanılır. 


CREATE TABLE #tablo_adi(
     Alan1 tur1[(boyut1)] [[NOT] NULL],
     Alan2 tur2[(boyut2)] [[NOT] NULL],
     ...
     Alann turn[(boyutn)] [[NOT] NULL]
)

Oluşturulan geçici tablolar üzerinde normal bir tabloymuş ekleme, silme vs. gibi işlemler yapılabilir. Ancak bu tablolar, oturum kapatıldığında veya SQL Server durdurulduğunda silinir. Bunun dışında tablo "drop" komutu ile de silinebilir.

2. yöntem: Geçici tablo oluşturmanın bir diğer yolu, "tempdb" adlı veritabanı dosyasına bir tablo açmaktır. Bu veritabanındaki tablolar sadece SQL Server kapatıldığında silinir.

Genel yapısı şöyledir:
CREATE TABLE
tempdb..tablo_adi(
     Alan1 tur1[(boyut1)] [[NOT] NULL],
     Alan2 tur2[(boyut2)] [[NOT] NULL],
     ...
     Alann turn[(boyutn)] [[NOT] NULL]
)

Bu yöntemle oluşturulan geçici tablolar, SQL Server durdurulduğu anda kaybolur. Çünkü "tempdb" adlı veritabanı SQL Server açıldığı anda boş bir hale getirilecektir. Bazen kullanıcı çıkış yaptığı halde geçici tablonun saklanması ihtiyacı olabilir. Bu tür durumlarda, geçici tablo SQL Server kapanıncaya kadar hafızada kalıp, SQL Server kapatıldığında silinecekse, "tempdb" veritabanında tablo açma yöntemi kullanılabilir.

Geçici tabloların özellikleri:

  • Saklı yordam (Stored Procedure) içerisinde geçici tablo kullanılabilir; ancak, kullanıcı tanımlı fonksiyon (User Defined Function - UDF) içerisinde geçici tablo yaratılamaz.
  • Normal tablolarda olduğu gibi geçici tablolarda da indeks (index) oluşturabilir ve kimlik (identity) alan tanımlanabilir.
  • Geçici tabloların farklı kullanıcılar tarafından aynı anda oluşturulma ihtimalleri vardır. Bu durumda sistem kendilerine benzersiz (unique) bir id ataması yaparak isim çakışmalarını engeller.