3 Kasım 2008 Pazartesi

SQL İpuçları

Bu yazımda sizlere SQL hakkında bazı ipuçları vereceğim. SQL gerçekten mükemmel bir dil. Normal bir programlama diliyle yapabildiğimiz her şeyi SQL ile yapabiliyoruz. Veritabanından çektiğimiz verilerin mutlak değerini almak, karekökünü almak, Convert işlemi uygulamak ve bunun gibi birçok işlemi SQL ile yapabiliyoruz.

Bu konu için aslında çoğu programcının başına gelen bir problemden bahsedeyim. Bu problem, SQL Server ile Visual C#.NET’in farklı tarih formatları kullanması ile oluşan bir problemdir. (Bazılarınızın gülümsediğini hissediyorum :)) Bu problem .NET’in tarih formatının "dd.MM.yyyy" olması, SQL Server’in tarih formatının ise "MM.dd.yyyy" olması ile ortaya çıkar. Bunu çözmek için önceden (aslında şimdi de) C#’da

string tarih = DateTime.Now.Month.ToString() + "." + DateTime.Now.Day.ToString() + "." + DateTime.Now.Year.ToString();

string tarih = DateTime.Now.ToString("MM.dd.yyyy");

System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-GB");

string tarih = Convert.ToDateTime(txtTarih.Text, culture);

gibi ifadeler kullanıyordum. Eminim ki birçoğunuz da bunlara benzer şekillerde bir çözümler bulmuştu. Ama bu çözümler SqlDataSource’da otomatik olarak oluşturduğumuz update ve insert cümlelerinde pek fazla işe yaramaz. (Tabi siz insert ve update alanlarını TemplateField olarak ayarlayıp kod tarafında işlem yapmak isterseniz bunları kullanabilirsiniz) Bu sorunun SQL ile çözümü ise

INSERT INTO TABLO(kisi, tarih) VALUES(@kisi, CONVERT(datetime, @tarih, 103))

şeklindedir. Burada CONVERT() fonksiyonu, gelen parametreyi herhangi bir SQL veri tipine çevirmemize yarar. 103 ise "dd/MM/yyyy" tarih formatını belirtmemize yarar. Bu kısma 108 girdiğimizde saat değerini elde ederiz. ("HH.mm.ss") Biz burada SQL Server’a hangi formatta veri gönderdiğimizi belirtiyoruz. O da hangi formatta olduğunu anlayıp o şekilde işlem yapıyor. Eğer formatını belirtmezsek

“The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.The statement has been terminated.”

gibi bir hata ile karşılaşırız.
Tarih formatlamanın Oracle’daki karşılığı ise TO_DATE() fonksiyonudur. Bu şekilde girilen bilgiyi tarih bilgisine dönüştürüp Oracle’a kaydedebilirsiniz. Ayrıca Oracle’da tarihe göre arama yapabilmek için bu fonksiyonu kullanmak zorundasınızdır. Kullanılışı ise

TO_DATE(@tarih, 'dd.MM.yyyy')

şeklindedir.

Tarih formatlarını SQL Server Books Online’da bulabilirsiniz. Bazılarını vereyim.

101 mm/dd/yy
102 yy.mm.dd
103 dd/mm/yy
104 dd.mm.yy
108 hh:mm:ss
113 dd mon yyyy hh:mm:ss:mmm(24h)

SQL’in bunun gibi birçok fonksiyonu vardır. Bunlar “abs(), sqrt(), cast(), sum(), avg(), …” gibi fonksiyonlardır. Bu fonksiyonlarla mutlak değer, karekök, ortalama, toplam gibi işlemler yapabilirsiniz.

Ben bunları zaten C# ile yada Java ile yapıyorum diyebilirsiniz. Size bir hikaye anlatayım. Mesela siz 3 ayrı veritabanından (biraz abartayım dedim :)) veri çekip bir GridView’de göstermek istiyorsunuz. Verileri çekme işini SqlDataSource ile değil de kod tarafında yapacaksınız. Ve GridView’e kod tarafında DataBind() edeceksiniz. Gelen verilerin içinde ondalıklı sayılar var ve siz bu sayıların virgülden sonra sadece üç hanesinin olmasını istiyorsunuz. Eğer SqlDataSource ile yapıp tek bir tablodan veri çekseydiniz GridView’in kolonlarının DataFormatString özelliğinden bunu rahatlıkla yapabilirdiniz. Ama kod tarafındayız. Gelin şu sorguyu yazalım ve işkence çekmekten kurtulalım.

(tablolarımızda kayıtlı pi sayıları olduğunu düşünelim.
Birinci tablomuzda pi1 = 3,1428571428571 ,
ikinci tablomuzda pi2 = 3,14285714 ,
üçüncü tablomuzda pi3 = 3,14286)

SELECT ROUND(t1.pi1, 3) AS Pi FROM veritabani1.dbo.[tablo1] as t1 union SELECT ROUND(t2.pi2, 4) AS Pi FROM veritabani2.dbo.[tablo2] as t2 union SELECT ROUND(t3.pi3, 0) AS Pi FROM veritabani3.dbo.[tablo3] as t3

Sorgumuz çalıştığında aşağıdaki tabloyu üretir.

Pi
3,142
3,1429
3

Gördüğünüz gibi ROUND() fonksiyonu yukarı doğru yuvarlama yaparak işlem yapıyor. Bu kadar basit bir şey için ben bunu C# ile zaten yaparım diyen yoktur herhalde.

Sormak istediğiniz bir şey varsa bana mail atabilir ya da bu yazı için yorum yapabilirsiniz.

Hiç yorum yok:

Yorum Gönder

Related Posts Plugin for WordPress, Blogger...