MSSQL Nvarchar to Decimal Convert Fonksiyonu
Bir program yazımına başlanıldığında nedendir bilinmez ama işin en önemli kısmı olan veritabanı planlama ve tasarım aşamaları hep unutulur yada “aman sen de…” diyerek tüm kolonlar nvarchar yada benzer string yapılarda tanımlanır.
Program bu şekilde elbet çalışacaktır, fakat yazılımın performansı son derece düşecektir. Şöyle ki;
Elimizde 1 milyon satırı olan bir tablomuz olsun ve yapılmak istenen şey belirli tarih aralığındaki satışların toplam ve ortalama değerlerini hesaplamak olsun.
Hatalı tasarlanmış bir veri tabanında bu durumda yapılacak en iyi şey tüm yükü yazılıma bırakarak
- önce tüm veritabanını sorgulamak,
- text olarak tanımlı tarih alanlarını belleğe alıp convert etmek
- bu tarih alanlarına göre satış rakamlarını belleğe almak
- ve toplam satış ve ortalama satış değerlerini hesaplamak için bir ton convert ve matematiksel işlemleri yapmak olacaktır.
Peki performans bu işin neresinde? tabi ki hiç bir yerinde yok. Hele de sürekli işlem yapılan bir sunucuda bu işi çevireceksek işlemi başlattığımız andan itibaren 1-2 bardak çay içecek zamanımız olacağı kesindir.
Eğer tablomuz düzgün tasarlanmış olsaydı, o zaman ne yapardık?
select sum(satis) toplamsatis from satislar where satistarihi between '01-01-2012' and '31-12-2012'
select avg(satis) ortalamasatis from satislar where satistarihi between '01-01-2012' and '31-12-2012'
sonra da bu sorgudan dönen toplamsatis ve ortalamasatis bilgilerimizi programda istediğimiz gibi kullanabiliriz.
İyi ama ya veri tabanını başkası tasarlamış ve binlerce satır satış rakamını decimal olarak convert yapma işi (hamallığı) bize kalmışsa, işte bu kötü bir durumdur.
Çünkü hatalı veri girişinden sebep text alanlara gereğinden fazla nokta konulmuş da olabilir. Bu durumda normal bir replace yada cast işlemi işimizi görmez. Çünkü decimal alanın ayraç bilgisi (,) işaretidir.
Bu işlemi yapabilmek için bir fonksiyon yazdım. Bu fonksiyon ile nvarchar alanda tanımlanmış hatalı noktalama yapısı düzgün bir noktalama yapısına çevriliyor.
GO /****** Yazan:Burak ŞEKERCİOĞLU Tarih:28.01.2013 Açıklama: Nchar veya Nvarchar olarak tanımlanmış kolonlardaki decimal ifadelerin yazım hatasının düzeltilerek Decimal tipine dönüşümü sağlar. ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[fn_nchar2decimal] ( @veri as nvarchar(max) ) RETURNS nvarchar(max) AS begin declare @donusum nvarchar(max) declare @karakter int declare @nokta int declare @noktasayisi int set @noktasayisi=0 set @karakter=1 set @donusum='' WHILE (@karakter>0) begin set @karakter=charindex('.',@veri,@karakter+1) if (@karakter>0) begin set @nokta=@karakter set @noktasayisi=@noktasayisi+1 end end if (@noktasayisi>1) begin set @donusum=replace(substring(@veri,1,@nokta-1),'.',',') set @donusum=@donusum + substring(@veri,@nokta,len(@veri)) end if (@noktasayisi=1) begin set @donusum=replace(@veri,'.',',') end return @donusum end
bu fonksiyonu test etmek istersek;
select dbo.fn_nchar2decimal(‘1243.4234.234.423.4234.31’) as sonuc şeklinde basitçe kullanabiliriz.
görüldüğü üzere hatalı kolon bilgisinde ne kadar nokta olursa olsun 1 den fazla nokta varsa en sağdakini her zaman ondalık/kuruş olarak tanımlamaktadır.
Bu fonksiyonu UPDATE cümleciğinde kullanarak ALTER COLUMN öncesinde verilerin güncellenmesini de sağlayabiliriz.
Update satislar set satistutari=dbo.fn_nchar2decimal(satistutari)
sonrasında da ister kolonu decimal yapın ya da money artık rahatça dönüşüm yapılabilir.
Kolay gelsin.