Veritabanlarımız gün içerisinde pek çok yöntem ile beslenmektedir. Bunlardan biri de .csv ya da .txt uzantılı veri tipi barındırmayan dosya formatlarıdır. Yapısal bir bütüğünlüğü olmayan dosyalarımızı veritabanına aktarım sırasında bizlere pek çok süpriz yaşatabiliyor.
Dosya içerisinde bulunan veriler, data tiplerimiz ile uyuşmadığı ya da istediğimiz formatlar kapsamında olmadığında bunları düzeltme ya da silme gibi çeşitli yöntemlere gidebiliriz. Fakat, burada daha fazla vakit harcadığımız bir kısım daha var. O da hataların tespiti için harcadığımız süredir.
Bu yüzden karşılaşabileceğiniz bir kaç durum ile ilgili pratik çözüm önerilerinden bahsedeceğim.
TRY_CAST ve TRY_CONVERT
Bu fonksiyonların bize sağladığı en büyük avantaj verilerimizi istediğimiz data tipine çeviremediğimiz durumlarda hata vermek yerine bu satırlar için NULL değer atamasıdır. Böylece NULL değerleri filtreleyerek hangi satır üzerinde hatalı formatta kayıt var yakalayabiliyoruz.
Değişken içerisinde bulunan verimizi
- Normal bir CAST işlemi yaparak bize sonucu veriyor.
- Nokta yerine kullanılan virgülden dolayı DECIMAL’a CAST edilemediği için NULL veriyor
- Aynı şekilde CONVERT işlemi de yapılmaktadır. Tarih üzerine format verme gibi bütün işlemleri gerçekleştirebiliyoruz.
DECLARE @TestValue VARCHAR(50) = ‘100.30’
–Adım 1
SELECT TRY_CAST(@TestValue AS DECIMAL(18,2))
–Adım 2
SET @TestValue = ‘100,30’
SELECT TRY_CAST(@TestValue AS DECIMAL(18,2))
–Adım 3
SET @TestValue = ‘0000-00-00’
SELECT TRY_CONVERT(DATE,@TestValue,103)
Resim – 1
Bilimsel Gösterim
Bazı kaynaklar üzerinde DECIMAL değerlerinde “E-09” şeklinde bilimsel gösterimlere denk gelebiliriz.
Bunları normal bir şekilde tek seferde DECIMAL bir değere çeviremeyiz. Burada kullanmamız gereken püf nokta SQL Server’ın Mathematical Function’larından yararlanmaktır.
- TRY_CAST ile bakarsak CAST işleminin başarısız olduğu ve bunun sonucunda NULL değer elde ediyoruz
- ROUND matematik fonksiyonu olduğu için gelen veriyi anlayabiliyor ve ROUND fonksiyonunun çıktısını istediğimiz gibi CAST edebiliyoruz
- Aynı şeyi pozitif bir gösterim için denersek benzer sonuç elde edebiliyoruz
DECLARE @TestValue VARCHAR(50) = ‘5.0E-09’
–Adım 1
SELECT TRY_CAST(@TestValue AS DECIMAL(18,6))
–Adım 2
SELECT ROUND(@TestValue,6)
SELECT CAST(ROUND(@TestValue,6) AS DECIMAL(18,6))
–Adım 3
SET @TestValue = ‘5.0E+09’
SELECT ROUND(@TestValue,6)
SELECT CAST(ROUND(@TestValue,6) AS DECIMAL(18,6))
Resim – 2
ISNUMERIC
Verimizin sayısal değerlerden oluşuyorsa 1, değil ise 0 dönüyor.
DECLARE @TestValue VARCHAR(50) = ‘100’
–Adım 1
SELECT ISNUMERIC(@TestValue)
–Adım 2
SET @TestValue = ‘100A’
SELECT ISNUMERIC(@TestValue)
Resim – 3
ISDATE
Verimizin tarih formatına uygunsa 1, değil ise 0 dönüyor
DECLARE @TestValue VARCHAR(50) = ‘2018-08-30’
–Adım 1
SELECT ISDATE(@TestValue)
–Adım 2
SET @TestValue = ‘0000-00-00’
SELECT ISDATE(@TestValue)
Resim – 4
TRIM Problemi
Dosyadan bir tabloya aktardığımız verinin bazen WHERE koşulu içerisinde ya da JOIN ile başka bir tabloya bağladığımız da sonuç gelmediğini görebiliyoruz. Bu eşleştirme problemi ise bazen bir boşluk ya da silinemeyen gizemli bir boşluk olarak karşımıza çıkabiliyor.
Gizli bir boşluk olarak görülen karakterler aslında aşağıdaki karakterlerden oluşuyor.
CHAR(13) – CR (Carriage Return)
CHAR(10) – LF (Line Feed)
CHAR(9) – TAB
Değişkenimize CHAR(13) ile başlayan bir değer oluşturdum.
- Bu değerin önünce boşluk olduğunu gözle görmek zordur. Bu yüzden basit bir birleştirme işlemi ile başına ve sonuna işaret koyarak boşluğu görmeyi kolaylaştırıyoruz
- LTRIM ile başındaki boşluğu silmeye çalışıyoruz. Fakat, boşluk olmadığı için aynı şekilde duruyor
- ASCII karakter ile o bölgedeki karakterin ASCII’sini öğrenebiliriz
- Burada CHAR fonksiyonu içerisinde ASCII değeri ile REPLACE işlemi yaparak datamızı temizlemiş olduk
DECLARE @TestValue VARCHAR(50) = CHAR(13) +’TEST’
–Adım 1
SELECT ‘”‘+ @TestValue +'”‘
–Adım 2
SELECT ‘”‘+ LTRIM(@TestValue) +'”‘
–Adım 3
SELECT ASCII(LEFT(@TestValue,1))
–Adım 4
SELECT ‘”‘+ REPLACE(@TestValue,CHAR(13),”) +'”‘
Resim – 5
REPLICATE
Elinizde ürün kodu bilgileri olan bir veri seti var. Fakat, bunların başlarında bulunan sıfır değerleri olması gereken 5 karakterden az atılmış ya da hiç atılmamış olsun.
İşte bu gibi durumlar için REPLICATE gibi bir fonksiyondan yardım alarak istediğiniz adette karakter üreterek datanızı birbirine eşitlemek için veriyi manipüle edebilirsiniz
DECLARE @TestValue VARCHAR(50) = ‘100’
–Adım 1
SELECT REPLICATE(‘0’,5)
–Adım 2
SELECT REPLICATE(‘0’,5) + @TestValue
Resim – 6
STUFF
Beklediğimizin dışında gelen bir verilerin içerisinde bulunan yerlere eklemek ve değiştirme yaparak manipüle edebilirsiniz.
- 5 karakterin yerine onu değiştirmeden (değiştirmek isterseniz 1,2,n) ‘-‘ işaretiyle yılı ayırıyorum
- Ay ve Gün’ü de birbirlerinden ayırarak istediğim tarih formatını elde ediyorum
DECLARE @TestValue VARCHAR(50) = ‘20180830’
–Adım 1
SELECT STUFF(@TestValue,5,0,’-‘)
–Adım 2
SELECT STUFF(STUFF(@TestValue,5,0,’-‘),8,0,’-‘)
Resim – 7
Burada kullandığım bazı fonksiyonlar SQL Server’ın eski sürümleri tarafından desteklenmiyor olabilir. Fonksiyonların çalışmadığı noktalarda SQL Server sürümünüzün bu fonksiyonlar üzerindeki desteğini kontrol ediniz.
Bu konuyla ilgili sorularınızı alt kısımda bulunan yorumlar alanını kullanarak sorabilirsiniz.
Referanslar
TAGs:SQL Server, T-SQL, SQL komutları, Veri Kontrolü, Veri Temizleme, Data Cleaning