MSSQL Nvarchar to Decimal Convert Fonksiyonu

MS SQLBir 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

  1. önce tüm veritabanını sorgulamak,
  2. text olarak tanımlı tarih alanlarını belleğe alıp convert etmek
  3. bu tarih alanlarına göre satış rakamlarını belleğe almak
  4. 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.

nvarchar2decimal

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.

 

Loading