30 Aralık 2010 Perşembe

Sql'de Tarih Format Uyumsuzluğu

Sql'de en çok can sıkan konulardan biri de, datetime format uyumsuzluğu. Gün-ay-yıl mı olacak, ay-gün-yıl mı olacak, veya bize gönderilen dosyada daha farklı bir format varsa bunları nasıl istediğimiz formata çevirebiliriz gibi sorunlarla sürekli karşılaşmaktayız. Şimdi size, tüm tarih formatlarını içeren bir tablo ve bu formatların nasıl kullanılacağını gösteren sorguları göstereceğim.


SELECT convert(varchar, @tarih, 100) -- mon dd yyyy hh:mm

SELECT convert(varchar, @tarih, 101) -- mm/dd/yyyy              

SELECT convert(varchar, @tarih, 102) -- yyyy.mm.dd       

SELECT convert(varchar, @tarih, 103) -- dd/mm/yyyy

SELECT convert(varchar, @tarih, 104) -- dd.mm.yyyy

SELECT convert(varchar, @tarih, 105) -- dd-mm-yyyy

SELECT convert(varchar, @tarih, 106) -- dd mon yyyy

SELECT convert(varchar, @tarih, 107) -- mon dd, yyyy

SELECT convert(varchar, @tarih, 108) -- hh:mm:ss

SELECT convert(varchar, @tarih, 109) -- mon dd yyyy hh:mm:ss:mmm 

SELECT convert(varchar, @tarih, 110) -- mm-dd-yyyy

SELECT convert(varchar, @tarih, 111) -- yyyy/mm/dd

 

-- yyyymmdd - ISO date format - international standard  

 

SELECT convert(varchar, @tarih, 112) -- yyyymmdd

SELECT convert(varchar, @tarih, 113) -- dd mon yyyy hh:mm:ss:mmm

SELECT convert(varchar,@tarih, 114) -- hh:mm:ss:mmm(24h)

SELECT convert(varchar, @tarih, 120) -- yyyy-mm-dd hh:mm:ss(24h)

SELECT convert(varchar, @tarih, 121) -- yyyy-mm-dd hh:mm:ss.mmm

SELECT convert(varchar, @tarih, 126) -- yyyy-mm-ddThh:mm:ss.mmm

 

-- Without century (YY) date / datetime conversion 

 

SELECT convert(varchar, @tarih, 0)   -- mon dd yyyy hh:mmAM (or PM)

SELECT convert(varchar, @tarih, 1)   -- mm/dd/yy

SELECT convert(varchar, @tarih, 2)   -- yy.mm.dd          

SELECT convert(varchar, @tarih, 3)   -- dd/mm/yy

SELECT convert(varchar, @tarih, 4)   -- dd.mm.yy

SELECT convert(varchar, @tarih, 5)   -- dd-mm-yy

SELECT convert(varchar, @tarih, 6)   -- dd mon yy

SELECT convert(varchar, @tarih, 7)   -- mon dd, yy

SELECT convert(varchar, @tarih, 8)   -- hh:mm:ss

SELECT convert(varchar, @tarih, 9)   -- mon dd yyyy hh:mm:ss:mmm 

SELECT convert(varchar, @tarih, 10)  -- mm-dd-yy

SELECT convert(varchar, @tarih, 11)  -- yy/mm/dd

SELECT convert(varchar, @tarih, 12)  -- yymmdd

SELECT convert(varchar, @tarih, 13)  -- dd mon yyyy hh:mm:ss:mmm

SELECT convert(varchar, @tarih, 14)  -- hh:mm:ss:mmm(24h)

SELECT convert(varchar, @tarih, 20)  -- yyyy-mm-dd hh:mm:ss(24h)

SELECT convert(varchar, @tarih, 21)  -- yyyy-mm-dd hh:mm:ss.mmm

SELECT convert(varchar, @tarih, 22)  -- mm/dd/yy hh:mm:ss AM (or PM)

SELECT convert(varchar, @tarih, 23)  -- yyyy-mm-dd

SELECT convert(varchar, @tarih, 24)  -- hh:mm:ss

SELECT convert(varchar, @tarih, 25)  -- yyyy-mm-dd hh:mm:ss.mmm


Böylece bundan sonra sql'de alınan "The conversion of a varchar data type to a datetime data type resulted in an out-of-range value." vb. gibi hataların, üstteki tablodaki formatlara, belirtilen sorguları yazarak üstesinden gelebileceğiz.

Not: @tarih yerine siz de kendi tarih değişkeninizi giriniz.

25 Aralık 2010 Cumartesi

.Net Teknolojisinde PageMethod Kavrami

Daha onceden konustugumuz gibi, bazi durumlarda sitemizde tum sayfanin post edilmesindense, sadece belli bolumlerinin post edilmesini isteriz. Peki ne gibi fayda saglar bu durum? Basit bir senaryo uzerinden anlatmak gerekirsek;

Bir uyelik formunda, sehirleri bir dropdownlistten alalim. Dropdownlist'in enable postback ozelligini acik birakirsak, her sehri sectigimizde sayfa post edilir. Ama bizim isteğimiz sadece o dropdownlist'in post edilmesi, tüm sayfanın degil. Zaten tum sayfa post edilse, life cycle sürecine tekrar başlayacağından, textbox'lar, butonlar, vs... tüm kontroller yeniden yükleneceginden, o ana kadar girmis oldugumuz tum kayitlar silinecekti. Hoop en bastan doldurmaya basla tekrar, isin yoksa. Tum bunlarin otesinde, tum sayfanin post edilmesine ne gerek var. Biz sadece sehirler kismini degistiriyoruz, neden bize tekrar tum sayfanin bilgileri geliyor. Gereksiz yere bilgiler yukleniyor ve dolayisiyla sayfa acilimi biraz daha gecikiyor.

İste bu veri fazlaligindan, gecikmeden, post edildikten sonra verilerin kaybolma durumundan kurtulmak icin yapmamiz gereken, update panel'in icine dropdownlist'i ekleyip, triggers property'sinden hangi control icin bu islemi yapacagimizi (bu ornek icin dropdownlist) hangi eventinde(selectedindexchanged) sadece bu kontrolun postback edilecegini belirtiriz. Bunu yaptigimiz zaman goruruz ki, sayfanin yuklenmesi daha hizli olacak, progress bar yuklenmeyecek, daha buyuk veriler icin yuklenme sirasinda asenkron uygulamaya(yukleme sirasinda degisiklik yapilabilinecek sayfada) izin verilecek. Ayrica tum sayfa yuklenmeyeceginden, 500 byte'lik yuklenme yaklasik 150lere vs. dusecek (sayfadaki kontrollere gore degisebilir.) Viewstate icerisinde bazi bilgilerin geldigini gorecegiz.

Bu senaryodan bile daha iyi bir ozelligimiz var bizim. Neden her defasinda viewstate doluyor. 193 byte yerine, bize sadece dropdownlist icerisindeki bilgi gelsin. DDL icerisinde 10 secildiyse, sadece 10 gelsin. Yani bize sadece data gelsin.

Sadece data gelmesini istememiz, bize web servisleri hatirlatiyor. Orada, web methodlarimiz, baska server uzerindeyken, baska makinenin serverindan biz methodlari cagirirken, burada kendi makinemizde WebMethod yazip onu cagiracagiz. Cagirma isini de, UpdatePanel'de ScriptManager kendi basina yazarken, biz burada ekstra bilgi gelmemesi icin biz yazacagiz.

Tum bu bilgiler cercevesinde, simdi kisa bir ornek ile pekistirelim. Once kendi web methodumuzu yazalim, ardindan sayfanin source kisminda, iki javascript fonksiyonu yazalim. Birincisi, bizim yazdigimiz webmethodu cagirsin; ikincisi de, yazdigimiz webmethoddan geriye donen degeri label'a yazsin.

[WebMethod]

public static string GetStokMiktari(string urunKod)

{

return urunKod;

}

Yazdigimiz bu webmethod'u okumak icin su js fonksiyonunu yazariz.

function CallGetStokMiktari() {

var ctrl = document.getElementById('TextBox1');

PageMethods.GetStokMiktari(ctrl.value,CallBackGetStokMiktari);

}

GetStokMiktari methodumuz, ilk parametre olarak TextBox'in degerini alirken (html tabanli programlamada textbox'in text'inden soz edemeyiz,textbox'in value'si olur. Aslinda textbox'da input type="button" 'a donusur.)

Simdi de TextBox'dan okudugumuz degeri, Label'a yazan JavaScript fonksiyonunu yazalim;


function CallBackGetStokMiktari(result) {

var ctrl = document.getElementById('Label1');

ctrl.innerText = result;

}

TextBox'dan okunan verinin Label'a aktarilmasi icin bir button koyalim, buttona tiklaninca label'in ici dolsun. Yapmamiz gereken sadece, buttonun onclickine yazdigimiz js fonk'unun adini vermek olacak.

input id="Button2" type="button" value="button" onclick="CallGetStokMiktari()" />


Kodumuzu derlediğimiz zaman, calismadigini gorecegiz. Bunun nedeni, ScriptManager arka planda bazi ozel js fonksiyonlarini yazmamasi. Bunun nedeni, bizim WebMethod yazdigimizi bilmemesi. Eski senaryoda biz UpdatePanel surukleyerek ona belirtmis oluyorduk, fakat simdi sadece kodlarla kendimiz yazdigimizdan, ozellikle ScriptManager'e soylememiz gerekir bizim WebMethod yazdigimizi.ScriptManager'imize su kodu eklersek sorun kalmayacaktir.

asp:ScriptManager EnablePageMethods="true" ID="ScriptManager1" runat="server">

asp:ScriptManager>

Yazdığımız js fonksiyonları ile birlikte, bize sadece textbox,a girilen değer gelecektir. Ne sayfa post edilecektir, ne de viewstate içerisinde updatepanel vs... gibi kontrollerin kodları gelecektir. Böylece sayfa açılımı ve performans son derece artacaktır. UpdatePanel kullanarak 600-700 mblık veri yükleme işlemi, şimdi sadece 10-15 mb civarında olacaktır.Gördüğünüz gibi bazı durumlarda sadece UpdatePanel kullanmak da performansı artırmıyor. Tabiki tüm sayfanın post edilmesine nazaran bir artıştan söz edebiliriz ama bize gerekli olan sadece TextBox'ın Text'i veya DropDownList'in SelectedItem'ı olacağından, tekrar viewstate'i şişirmeye veya tüm sayfanın bilgilerini tekrar sayfaya yüklemeye gerek kalmayacaktır.

Burada, kendi yazdigimiz bir webmethod uzerinden eristik. Disardan alinan hazir webservis methodlarini kullanarak da bu islemi yapabiliriz. Degisen hicbir sey olmayacak. Sadece WebServis makalemde belirttigim gibi WSDL tanitilacak. Yine webmethodun geri donus degerine gore iki js fonksiyonu yazilir. Tek onemli nokta, bizim disardan aldigimiz webmethodun, js ile kullanilabilmeye elverisli olmalidir...

6 Aralık 2010 Pazartesi

Bulk Insert(Not Defterinden Sql'e Veri Girişi)

Bulk insert genellikle sql tabloları arasında yapılan kopyalama işlemleri olarak bilinir ama ben size bir txt (txt,csv .. vs gibi dosyaları da destekliyor) dosyasından sql tablolarına insert işlemini anlatacağım. Nasıl senaryolarda kullanılır. Bir banka, günlük satış raporlarını size txt uzantılı yollar ve bu bilgiler de veritabanına işlenmesini isteyebilir. Bunun için yapacağımız yöntem, visual studio yardımıyla tüm verileri okuyup, verileri split ederek, veri veri sql'e giriş yapmak. Fazlasıyla gereksiz işlemler ile zaman kaybı had safhada olacaktır. İşte Bulk Insert sayesinde bunları sadece 30 sn içinde yapmış olacağız.

Diyelim ki txt dosyanız şöyle olsun

Ad Soyad Yaş
Ali;Vural;29
Veli;Bak;33

Kural, iki verinin belli bir formatta ayrılmasıdır. Örneğin burda kolonlar, ';' ile ayrılmış. Bu ',' , '-' , '/' veya bir karakter boşluk ' ' veya bir tab uzaklık '\t' olabilir. Tüm bunlar için yazmamız gereken kod;

bulk insert Table_1

from "Desktop\bank.txt"

with

(

firstrow=2, --ilk satırımız başlıklardan oluştuğundan 2. satırdan başlatırız

rowterminator = '\n', --satır ayıracı

fieldterminator = ';' --iki kolon arası ayıracı

)

Not: Bulk insert yaparken, sqlin kullandığı default fieldterminator bir tab boşluk bırakan '\t' iken, rowterminator için ise alt satıra geçen '\n' dir.

5 Aralık 2010 Pazar

Web Service(Web Servis) Kavramı

Hepimiz, hergün farklı farklı browserlardan internete giriyoruz. Gireceğimiz sitenin adresini yazıyoruz, yaklaşık 3-4 sn bekledikten sonra o site karşımıza geliyor. Ne kadar basit değil mi? Bilmeyiz ki arka planda neler dönüyor. Yada başka bir senaryo daha, bazı sitelerde (genellikle e-ticaret sitelerinde) dolar,euro kurunu bize gösterirler. Gün içinde de sürekli değişir. Bu yapı nasıl işliyor? Ekranın karşısında, bi yandan merkez bankasını takip edip, diğer yandan da o değişiklikleri siteye mi yansıtıyorlar. Tabi ki cevabımız hayır.

Şimdi bu iki senaryoyu birleştirelim;

Kullanıcı sitenin adresini yazdığı zaman, arkada life cycle dediğimiz süreç başlıyor. IIS dediğimiz (Internet Information Services) yapı devreye giriyor ve bu sitenin uzantısına, yapısına ...vs bakarak, sitenin aspx mi, java mı, php mi olduğuna karar veriyor. aspx olan sayfayı Work Processor dediğimiz yapıya aktarıyor ve bu yapı da bize o sayfanın html kodlarını render ediyor ve browser'da geri gönderiyor. Her talepte bu sistem tekrar en baştan çalışıyor. Dolar-Euro kuruna gelecek olursak da, sürekli aktif olarak değişen bu sistem için tekrar tekrar html kodlarını göndermeye ne gerek var değil mi? Ayrıca sürekli ekran başında değiştirmek ne kadar da saçma geliyor.

İşte web servis dediğimiz yapı, istemciye html kodlarının değil de sadece datanın gönderildiği yapıdır. Dolayısıyla sadece data gönderildiğinden, senaryomuz üzerinden konuşursak, dolar/euro kurunda değişen her fiyat için merkez bankasının yazmış olduğu web service değiştiğinde otomatik olarak bizim sitemizdeki görüntü de değişecektir. Böylece sitemiz sürekli güncel kalmış olacak...

Kısaca kullanımından bahsedelim. Class yazımından hiç bir farkı yok. Tek farkı kendi projemizde veya makinemizde olmayacak bu class. Uzak bilgisayardan çağıracağız bu servislere. Dolayısıyla da proxy dediğimiz vekil metotlara ihtiyacımız olacak çağırma işlemi yaparken. Şimdi kısaca web service nasıl çağrılır, projede nasıl kullanılır, kısaca üstünden geçelim.

Öncelikle Web servis yazmak için projemize sağ tıklayıp add new item ile Web Service ekliyoruz. Eklediğimiz zaman göreceğiz, hem asmx uzantılı, hem de asmx.cs uzantılı iki dosyayı eklediğimizi göreceğiz. 'cs' ile csharp dosyası olduğunu anlıyoruz ve işte buradan web servisimizi yazacağız. Kısaca bir metot yazalım buraya.

[WebMethod]

public int Test(int Parametre)

{

return Parametre+ 5;

}

WebMethod attribute'ini yazarak yazdığımız metodun Web Servis Metodu olduğunu belirtiyoruz. Daha sonra çalıştırdığımızda,

gibi ekran ile karşılaşacağız. Bu sayfada denemelerimizi yapabiliriz. Ayrıca Service Description'ı tıkladığımızda bize bir url bilgisi verilecek. İşte bu url'yi, sayfamızda add service reference diyip, adres satırına yapıştırıp go dediğimiz zaman web servisimizi projemize tanıtmış olacağız. Bu url bilgisi WSDL'dir. Yani bize, web servis hakkında bilgiler veren, hangi parametreleri aldığını, geriye ne döndürdüğünü, ne tür işlemler yapıldığı gibi bilgileri verir. Bundan sonra da projemizde, servis referansını eklediğimizde oluşan namespace ile web servisimize rahatlıkla erişmiş olacağız.

protected void Page_Load(object sender, EventArgs e)

{

Service.WebServiceSoapClient service = new Service.WebServiceSoapClient();

int a = 5;

Label1.Text = service.Test().ToString();

}


Gördüğünüz gibi, servisimize rahatlıkla erişip, değeri web sitemizde bir labe'in içine yazdırdık. Dışardan alınan web servis hizmetleri de yine aynı şekilde. WSDL aracılığıyla önce web methodun özelliklerini tanıyıp, add service reference ile urlsini girdikten sonra, o servise erişip, gerekli parametreleri verdikten sonra geri dönüş değerine göre istediğimiz işlemleri yapabiliriz.

Web Servisi ile ilgili önemli notlar:

  • Web servisleri platform bağımsızdır. Yani C# ile yazılmış bir web servis, java uygulamalarında çalışır. Tersi de geçerlidir yine. Tek yeterli şart,kullandığımız yapının diğer dillerde de destekleniyor olmasıdır. Örneğin generic metodlar, java dilinde bulunmadığından yazacağımız generic web servis javada çalışmayacaktır.
  • Yazdığımız web servisteki metotlarımız geri değer döndürmelidir. Döndürmezse hata vermez fakat işe yaramaz. Geriye, int,string,decimal,int[],list döndürebilir. Fakat, örneğin fonksiyon int döndürse bile, bize gelen kodlar xml formatında olacaktır. Yani metot stringe dönüştürülüp, xmle kaydedildikten sonra web servisten bizim projemize değerler gelir.