25 Ocak 2012 Çarşamba
Sql Open Query ile LinkedServer Hatası
The OLE DB provider "SQLNCLI10" for linked server "LinkedServer" supplied inconsistent metadata for a column. The name was changed at execution time.
yapmamız gereken, openquery ile çalıştırdığımız procedure sorgusuna SET FMTONLY OFF sorgusunu eklemek olmalı. Sonuç olarak, procedure'u execute ederken;
SELECT * FROM OPENQUERY('LinkedServer','SET FMTONLY OFF EXEC Procedureİsmi')
30 Ekim 2011 Pazar
23 Ekim 2011 Pazar
Sql'de Recompile
Parsing, yazdığımız kodun syntax olarak hata içerip içermediğinin kontrol zamanıdır,
Compiling, yazdığımız prosedürün execution planını oluşturup bunu geçici hafızaya atılma zamanıdır,
Executing ise anlaşılacağı üzere kodun çalıştığı anda DML'e bildirilen zamandır.
İşte compiling zamanında execution plan'ın hafızaya atılması bazı durumlarda kodumuza hız katabilir. Fakat bazı durumlarda da tablo yapıları veya indeksler çok sık değiştiğinden bu hafızaya atılan execution plan'lar yarar yerine zarar getirir. Bunu nasıl anlarız? ilk derlemede prosedürümüz hızlı çalışıp, sonraki çalıştırmalarda gözle görülür bir yavaşlama varsa, nedeni bu olabilir. Bundan kaçınmak için yapmamız gereken RECOMPILE keyword'unu prosedüre tanıtmak. Kısaca kullanılışı;
Böylece Recompile yazarak, artık execution plan'ın hafızaya atılmasını engelledik.
7 Temmuz 2011 Perşembe
Sql'de Truncate Table Kavramı
Peki bu iki komut arasındaki fark nedir?
Kısaca, maddeler halinde yazalım.
- Öncelikle, Truncate kavramı ile bir şarta bakmaksızın tüm tablomuzu boşaltırız. Delete komutunda Where şartı ile belli şartlara bağlayabiliriz.
- Bence en önemli farklarından birisidir şimdiki maddemiz, Truncate Table yapınca, o tablodaki identity kolonumuz en baştan başlar. Ama Delete yaparsak, en son kaçıncı id'de kalmışsa, oradan devam eder.
- Truncate Table, Transaction içerisinde kullanılırsa ve işlemimiz rollback olursa geri alınamazlar. Delete komutunda geri alabiliriz.
- Truncate Table yaptığımızda, eğer o tablo üzerinde Delete Trigger'i varsa, bu trigger tetiklenmez. Delete komutlarında ise tetiklenir.
- TRUNCATE TABLE Tablo1
- DELETE FROM Table1
- DELETE FROM Table1 WHERE ID=5
5 Temmuz 2011 Salı
İlişkili Tablolarda Veri Silme (Delete Join)
Örnek senaryomuz, AdventureWorks üzerinden AltKategorileri 'G' ile başlayan ürünleri silmek istensin bizden. Gördüğünüz gibi, tek tablo işimizi görmüyor. Product tablosundan kayıt sileceğiz ama, bu tablo üzerinden AltKategori isimlerine erişemiyoruz. İşte burada yapmamız gereken şey, iki tabloyu birleştirip, silme işlemini gerçekleştirmek. Bunun için yazmamız gereken kod şu şekilde olmalıdır;
29 Haziran 2011 Çarşamba
Stored Procedure'den Başka Bir SP Çağırmak (Output Parametresi)
Şimdi ufak bir senaryo üzerinden devam edersek daha iyi anlaşılacaktır. Öğrenci tablomuz olsun. ÖğrenciEkle ismindeki Stored Procedure'müz, tablomuza kayıt atsın. Ayrıca OgrenciLog tablosuna da, hangi öğrenci kayıt atılırsa, onun id'sini ekleyelim. Aslında bu örnekte birden fazla sp'ye ve tabloya gerek yok ama, sadece birbiriyle olan ilişkileri göstermek amacıyla basit bir örnek olarak düşündüm. Normalde, birbirinden bağımsız, 30-40 kolonluk bir tablo olduğunu düşünebilirsiniz...
İlk procedure'müz basit olarak insert işlemi yapacak, ardından oluşacak id'yi de output parametresi yardımıyla, dışarıya aktaracağız. Yazacağımız sp kodu şu şekilde olmalıdır.
25 Haziran 2011 Cumartesi
Sql Recursive Functions(Rekürsif Fonksiyonlar)
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;
Sql Pivotlama Kavramı
Şimdi kısaca bir senaryo uydurup, beraber pivotlama yöntemiyle sorgumuzu yazalım.
Senaryomuz kısaca, AdventureWorks database'i içinde departman bazında kaç erkek, kaç bayan çalıştığını bulalım. Normal sorgulamamızı yaparsak önce departmanlara göre kaç bayan var, sonra yine departmanlara göre kaç erkek var alt alta göreceğiz, dolayısıyla satır sayısı fazla, okunulurluğu yok. Nasıl oluştuğunu görelim önce.
Sorgumuzu yazmak için 3 tabloya ihtiyacımız var. Bunlar Department, Employee ve EmployeeDepartmentHistory. Bunları birbirine joinledikten sonra cinsiyet ve departmana göre group by yapıp toplam sayı bizim istediğimiz sonuc olacak. Burada yeri gelmişken, kısaca sql'in kendi editöründen nasıl joinleme işlemlerini kolayca yapabileceğimizi göstereyim. Sorgu sayfasında herhangi bir yere sağ tıklayıp design query in editor dedikten sonra önümüze bir ekran gelecek. Add Table penceresinden yukarıda bahsettiğim üç tabloyu seçtiğimizde önümüze şu şekilde bir diyagram getirecek.
24 Mayıs 2011 Salı
Sql'de İlişkili Tablolarda Güncelleme(Update-Join)
Cevap oldukça basit. Biz yine de daha anlaşılır olması bakımından, senaryo üzerinden gidelim. İki tablomuz olsun. Öğrenci tablosunda Numara ve Ad tutulsun, Not tablosunda da ÖgrenciNo ve Puan tutulsun.
create Table Ogrenci
(
OgrenciNo int,
OgrenciAd nvarchar(20)
)
create Table Puan
(
OgrenciNo int,
Puan int
)
update Puan set Puan=50 from Puan p join Ogrenci o on p.OgrenciNo=o.OgrenciNo where OgrenciAd='Ahmet Demir'
2 Nisan 2011 Cumartesi
@@Identity,Scope_Identity() ve IdentCurrent
1-@@IDENTITY:
Son işlem yapılan sorgudan elde edilen Id'yi elde etmemizi sağlar. Aşağıdaki örnekte, insert yapıldıktan sonra ortaya çıkan Id şu şekilde bulunmuştur.
3-IDENT_CURRENT('TabloAdı'):
Parametre olarak aldığı tablodaki son işlem yapılan id'nin sonucunu getirir. Kullanılışı;
27 Mart 2011 Pazar
Sql'de Rollup ve Cube Kavrami
Yellow Jerseys 4
Yellow Road Bikes 9
Yellow Road Frames 5
Yellow Touring Bikes 9
Yellow Touring Frames 9
seklinde bir cikti elde ederiz. Fakat bizim istedigimiz, yellow rengine sahip toplam kac urunun satildigi bilgisidir. Iste bunu yaparken yazdigimiz query’e with rollup komutunu eklersek, istedigimiz raporu eklemis oluruz.

Goruldugu gibi NULL yazan satir aslinda bizim rengi yellow olan urunlerimizin toplam sayisi. Yani Ara Toplam diyebiliriz. Peki cift tarafli toplam yapmak istersek..
Yapmamiz gereken tek sey with rollup yerine with cube yazmak olacaktir. Sonuc kumesinde hem renklere gore bir liste, hem de urunlere gore bir liste yapilip ara toplam belirlenecektir.
Ustteki iki ornekte soyle bir eksiklik gozumuze carpiyor. Ara toplamlarin bulundugu hucrelerde NULL yaziyor. Biz, sonuc kumesine bakarak buralarin ara toplam satiri oldugunu anliyoruz. Ama daha buyuk raporlamalarda, hem bu karisacaktir hem de kullaniciya boyle anlama zorlugu cekmek dogru bir durum degildir. Ayrica soyle bir karisiklikliga da sebep olabilir. Ornegin RoadBikes’larin renklerine gore ara toplam hazirlanirken,
RoadBikes NULL 44
oldugu zaman, ara toplam mi, renk mi veritabanindan NULL geliyor? Bunun anlasilamadigi durumlarda ciddi zararla meydana cikabilir.
Iste bu hatadan kurtulmak icin, ara toplam satirlarinda NULL yerine Ara Toplam yazmaliyiz. Grouping metotu sayesinde, eger bu satir ara toplam satiriysa, geriye 1 degerini dondurur, aksi taktirde burasi ara toplam satiri degildir. Basit bir case-when yapisiyla bunun da ustesinden gelebiliriz.
Simdi baska ornekten, hem Cube hem de grouping fonksiyonunu kullanarak daha iyi algilayalim yapmak istediklerimizi. Yine AdventureWorks veritabani uzerinden gidersek, yasadigi sehirlere gore bay ve bayan calisanlari listeleyen bir kod yazalim. Cift tarafli toplam olsun ama. Yani Seatle 30 erkek, 40 bayan vs. diye sehirlere gore erkek bayan sayilarini yazsin, en sona da toplam erkek, toplam bayan sayilari yazilsin.
Bu ornegimizde, rollup keywordunu kullanamayiz, cunku rollup ile sadece tek tarafli toplam elde ederiz. Burada kullanmamiz gereken komut, Cube’dur.
Yazacagimiz sorgu su sekilde olmalidir,
Ve en son satirda da;
NULL Genel Toplam 290 –Sehirlere gore Genel Toplam
NULL F 84
NULL M 206
Goruldugu gibi, hem sehirlere gore hem de cinsiyetlere gore toplam yapmis olduk. Grouping fonksiyonundan geriye 1 deger dondurenler icin Ara Toplam veGenel Toplam yazilarini yazdirmis olduk. Boylece ortaya cikabilecek olan yanlislarin onune gecmis olduk.
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.










