Sayıların Okunuşu (SQL Fonksiyonu)

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Sayıların Okunuşu (SQL Fonksiyonu)

Mesaj gönderen sabanakman »

s.a.
Burada rakamların okunuşunu (özellikle fatura tutarlarının yazıyla kısmı için) bulan kodu vermek istedim. Hatta aramak isterseniz tonlarca benzeri koda rastlayabilirsiniz. Oturup kendinizde yazabilirsiniz ama ben size kolaylık olsun diye bir örnek vermek istiyorum. Delphi fonksiyon olarak yazılan bir fonksiyon:
Eğer aramak isterseniz benzeri bir kodu her yerden bulabilirsiniz.

Kod: Tümünü seç

function Rakam(Sayi:Int64):String;
const n=9;
  Basamak:array[0..n]of String=('','Bin','Milyon','Milyar','Trilyon','Katrilyon','Kentrilyon','Sekstilyon','Septilyon','Oktilyon');
  Onlar:array[0..n]of String=('','On','Yirmi','Otuz','Kırk','Elli','Altmış','Yetmiş','Seksen','Doksan');
  Birler:array[0..n]of String=('','Bir','İki','Üç','Dört','Beş','Altı','Yedi','Sekiz','Dokuz');
var i:Byte; UcHane:Word; Yed,UcluHane:String; HangiBasamak:Byte;
    Negatif,BasamakYaz:Boolean;

 function Modu(var Sayisi:Word):Byte;
 begin
   Result:=Sayisi mod 10;
   Sayisi:=Sayisi div 10;
 end;

begin
  if Sayi=0 then
    Result:='Sıfır'
  else begin
    Negatif:=Sayi<0;
    if Negatif then Sayi:=-Sayi;
    Result:='';
    HangiBasamak:=0;
    while Sayi>0 do begin
      UcHane:=Sayi mod 1000;  Sayi:=Sayi div 1000;
      BasamakYaz:=UcHane>0;
      repeat
        UcluHane:='';
        if ((HangiBasamak=1) and (UcHane=1)) then Break;//sadece bin yazılacaksa
        i:=Modu(UcHane); UcluHane:=Birler[i];   //3 hanenin 1. si
        i:=Modu(UcHane); UcluHane:=Onlar[i]+UcluHane; //3 hanenin 2. si
        i:=Modu(UcHane);
        if i>0 then Yed:='Yüz' else Yed:='';
        if i>1 then Yed:=Birler[i]+Yed;
        UcluHane:=Yed+UcluHane;//3 hanenin 3. sü
      until True;
      if BasamakYaz then Result:=UcluHane+Basamak[HangiBasamak]+Result;
      inc(HangiBasamak);
    end;
    if Negatif then Result:='Eksi'+Result
    else //Delete(Result,1,1);
  end;
end;
Şimdi bunu SQL Server fonksiyonu haline getirelim. Ama SQL Server scriptinin dizileri desteklemediğini öğrenince hayallerim yıkıldı. Neyse benim için büyük engel olsa bile bunu halletmek çok sorun olmadı. SQL Server:

Kod: Tümünü seç

CREATE FUNCTION RakamOku (@Sayi bigint)
RETURNS nvarchar(300)
AS
BEGIN
DECLARE @n int,@i int,@UcHane int,@Yed nvarchar(300),@UcluHane nvarchar(300),
 @HangiBasamak int,@Negatif bit,@BasamakYaz bit,@SONUC nvarchar(300)
  SET @n=9
  SET @SONUC=NULL
  BEGIN
    SET @SONUC=''
    IF (@Sayi=0) SET @SONUC='Sıfır' ELSE BEGIN
      IF (@Sayi<0) BEGIN
        SET @Negatif=1
        SET @Sayi=-@Sayi
      END ELSE SET @Negatif=0
      SET @HangiBasamak=0;
      WHILE (@Sayi>0) BEGIN
        SET @UcHane=@Sayi % 1000
        SET @Sayi=@Sayi / 1000
        IF (@UcHane>0) SET @BasamakYaz=1 ELSE SET @BasamakYaz=0
        IF ((@HangiBasamak=1) and (@UcHane=1)) SET @UcluHane=''
        ELSE BEGIN
          SET @UcluHane=''
          SET @i=@UcHane%10 SET @UcHane=@UcHane/10
          SET @UcluHane=CASE @i
            WHEN 1 THEN 'Bir'
            WHEN 2 THEN 'İki'
            WHEN 3 THEN 'Üç'
            WHEN 4 THEN 'Dört'
            WHEN 5 THEN 'Beş'
            WHEN 6 THEN 'Altı'
            WHEN 7 THEN 'Yedi'
            WHEN 8 THEN 'Sekiz'
            WHEN 9 THEN 'Dokuz'
          ELSE '' END
          SET @i=@UcHane%10 SET @UcHane=@UcHane/10
          SET @UcluHane=CASE @i
            WHEN 1 THEN 'On'
            WHEN 2 THEN 'Yirmi'
            WHEN 3 THEN 'Otuz'
            WHEN 4 THEN 'Kırk'
            WHEN 5 THEN 'Elli'
            WHEN 6 THEN 'Altmış'
            WHEN 7 THEN 'Yetmiş'
            WHEN 8 THEN 'Seksen'
            WHEN 9 THEN 'Doksan'
          ELSE '' END+@UcluHane
          SET @i=@UcHane%10 --SET @UcHane=@UcHane/10
          IF (@i>0) SET @Yed='Yüz' ELSE SET @Yed=''
          IF (@i>1) SET @Yed=CASE @i
            WHEN 1 THEN 'Bir'
            WHEN 2 THEN 'İki'
            WHEN 3 THEN 'Üç'
            WHEN 4 THEN 'Dört'
            WHEN 5 THEN 'Beş'
            WHEN 6 THEN 'Altı'
            WHEN 7 THEN 'Yedi'
            WHEN 8 THEN 'Sekiz'
            WHEN 9 THEN 'Dokuz'
          ELSE '' END+@Yed
          SET @UcluHane=@Yed+@UcluHane;
        END
        IF (@BasamakYaz=1) SET @SONUC=@UcluHane+CASE @HangiBasamak
          WHEN 1 THEN 'Bin'
          WHEN 2 THEN 'Milyon'
          WHEN 3 THEN 'Milyar'
          WHEN 4 THEN 'Trilyon'
          WHEN 5 THEN 'Katrilyon'
          WHEN 6 THEN 'Kentrilyon'
          WHEN 7 THEN 'Sekstilyon'
          WHEN 8 THEN 'Septilyon'
          WHEN 9 THEN 'Oktilyon'
        ELSE '' END+@SONUC
        SET @HangiBasamak=@HangiBasamak+1
      END
      IF (@Negatif=1) SET @SONUC='Eksi'+@SONUC
    END
  END
  RETURN @SONUC
END
GO
İnşallah işinize yarar. İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Mesaj gönderen mkysoft »

Buna bir de Kuruş eklersek daha yararlı olur sanırım.
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Değiştirdim :)

Mesaj gönderen sabanakman »

Nasıl olduda yaptığım halde onuda paylaşmak aklıma gelmedi :) . Neyse güzel hatırlatman için sağolasın mkysoft.
Delphi Kodu:

Kod: Tümünü seç

function ParaOku(Sayi:Real):String;
var Tam,Ondalik:String; TamSayi:Int64;
begin
  Tam:='YTL';
  Ondalik:='YKr';
  TamSayi:=Trunc(Sayi);
  Result:=RakamOku(TamSayi)+' '+Tam;
  TamSayi:=Round((Sayi-TamSayi)*100);
  Result:=Result+' '+RakamOku(TamSayi)+' '+Ondalik;
end;
SQL Kodu:

Kod: Tümünü seç

CREATE FUNCTION ParaOku (@Sayi float)
RETURNS nvarchar(300)
AS
BEGIN
  DECLARE @Tam nvarchar(20),@Ondalik nvarchar(20),@SONUC nvarchar(300),
  @TamSayi bigint,@OndSayi int
  SET @Tam='YTL'
  SET @Ondalik='YKr'
  SET @TamSayi=@Sayi
  SET @SONUC=dbo.RakamOku(@TamSayi)+' '+@Tam
  SET @TamSayi=Round((@Sayi-@TamSayi)*100,2)
  SET @SONUC=@SONUC+' '+dbo.RakamOku(@TamSayi,@Dil)+' '+@Ondalik
  RETURN @SONUC
END
İyi çalışmalar.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
rsimsek
Admin
Mesajlar: 4482
Kayıt: 10 Haz 2003 01:48
Konum: İstanbul

Mesaj gönderen rsimsek »

Paylaşım için teşekkürler @sabanakman. Veri tabanı tarafta yapmak hiç aklıma gelmemişti doğrusu :roll: Bir de Firebird'e çevirdik mi tamamdır :wink:
Bilgiyi paylaşarak artıralım! Hayatı kolaylaştıralım!!
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Mesaj gönderen sabanakman »

Valla birisi sevabına yapsa süper olur. Çünkü hiç FireBird'de script yazmadım ama en kısa zamanda çalışacağımdır :) .
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
moonred
Üye
Mesajlar: 14
Kayıt: 05 Kas 2005 11:13
Konum: İstanbul
İletişim:

Mesaj gönderen moonred »

sabanakman çalışma için çok teşekkür ederim. Çok işime yaradı faydasını dille anlatamam gerçekten çok teşekkür ederim...
Kullanıcı avatarı
vampir261
Üye
Mesajlar: 298
Kayıt: 23 Kas 2004 03:22
Konum: Denizli

Mesaj gönderen vampir261 »

Güzel çalışma olmuş eline sağlık. Leziz olmuş :D
Kullanıcı avatarı
Lost Soul
Üye
Mesajlar: 1064
Kayıt: 01 Nis 2007 02:55
Konum: mekan ANKARA toprak ELAZIĞ
İletişim:

Mesaj gönderen Lost Soul »

Çok güzel bir çalışma. Teşekkürler. :)
akdatilla
Üye
Mesajlar: 292
Kayıt: 02 Nis 2006 06:04
Konum: Antalya

Mesaj gönderen akdatilla »

sabanakman arkadaşın yazdığı bu kodları incelemediğim için ben de farklı bir yoldan çözüme gittim.
İsteyen arkadaşlar aşağıdaki linkleri inceleyebilir.

Firebird için
viewtopic.php?p=124601#124601

SQLServer için
viewtopic.php?p=124597#124597
Cevapla