miércoles, 6 de enero de 2021

Números a letras SQL

 CREATE FUNCTION [dbo].[F_Unidades](@Numero AS bigint, @Estilo AS bit=0)              

RETURNS varchar(500)

AS                   

BEGIN                     

 DECLARE @Texto varchar(500)                   

 SELECT @Texto=''                     

 SELECT @Texto=                      

 CASE                     

  WHEN @Numero=0 THEN 'Cero '

  WHEN @Numero=1 THEN 'Uno '                 

  WHEN @Numero=2 THEN 'Dos '

  WHEN @Numero=3 THEN 'Tres '

  WHEN @Numero=4 THEN 'Cuatro '

  WHEN @Numero=5 THEN 'Cinco '

  WHEN @Numero=6 THEN 'Seis '

  WHEN @Numero=7 THEN 'Siete '

  WHEN @Numero=8 THEN 'Ocho '

  WHEN @Numero=9 AND @Estilo=0 THEN 'Nueve '

  WHEN @Numero=9 AND @Estilo=1 THEN 'Nove '

 END                     

 RETURN @Texto                     

END

GO

CREATE FUNCTION [dbo].[F_Decenas](@Numero AS bigint, @Estilo AS bit=0)              

RETURNS varchar(500)

AS                   

BEGIN                     

 DECLARE @Texto varchar(500)                   

 SELECT @Texto=''                     

 SELECT @Texto=                     

 CASE                     

  WHEN @Numero=0 THEN ' '                 

  WHEN @Numero=10 THEN 'Diez '

  WHEN @Numero=11 THEN 'Once '                 

  WHEN @Numero=12 THEN 'Doce '                 

  WHEN @Numero=13 THEN 'Trece '                 

  WHEN @Numero=14 THEN 'Catorce '                 

  WHEN @Numero=15 THEN 'Quince '                 

  WHEN @Numero>15 AND @Numero<19 

   THEN 'Dieci' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 1)

  WHEN @Numero=19 THEN 'Diecinueve '                  

  WHEN @Numero=20 THEN 'Veinte '                  

  WHEN @Numero>20 AND @Numero<30 

   THEN 'Veinti' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 1)                  

  WHEN @Numero=30 THEN 'Treinta '

  WHEN @Numero>30 AND @Numero<40 

   THEN 'Treinta y ' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)                  

  WHEN @Numero=40 THEN 'Cuarenta '                  

  WHEN @Numero>40 AND @Numero<50 

   THEN 'Cuarenta y ' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)

  WHEN @Numero=50 THEN 'Cincuenta' 

  WHEN @Numero>50 AND @Numero<60 

   THEN 'Cincuenta y ' +dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)                  

  WHEN @Numero=60 THEN 'Sesenta '

  WHEN @Numero>60 AND @Numero<70 

   THEN 'Sesenta y ' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)

  WHEN @Numero=70 THEN 'Setenta '

  WHEN @Numero>70 AND @Numero<80 

   THEN 'Setenta y ' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)                  

  WHEN @Numero=80 THEN 'Ochenta '

  WHEN @Numero>80 AND @Numero<90 

   THEN 'Ochenta y ' +dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)                  

  WHEN @Numero=90 THEN 'Noventa ' 

  WHEN @Numero>90 AND @Numero<100 

   THEN 'Noventa y ' + dbo.F_Unidades(RIGHT(CONVERT(varchar, @Numero), 1), 0)

  WHEN @Numero<10 THEN dbo.F_Unidades(@Numero, @Estilo)

 END                     

 RETURN @Texto                     

END

GO

CREATE FUNCTION [dbo].[F_Centenas](@Numero AS bigint, @Estilo AS bit=0)              

RETURNS varchar(500)

AS                   

BEGIN                     

 DECLARE @Texto varchar(500)                   

 SELECT @Texto=''                     

 SELECT @Texto=                     

 CASE                     

  WHEN @Numero=000 THEN ' '                 

  WHEN @Numero=100 THEN 'Cien '

  WHEN @Numero>100 AND @Numero<200 

   THEN 'Ciento ' + dbo.F_Decenas(RIGHT(CONVERT(varchar, @Numero),2),0)                  

  WHEN (@Numero>=200 AND @Numero<500) --or (@Numero>500 AND @Numero<1000) 

   THEN dbo.F_Decenas(LEFT(CONVERT(varchar, @Numero),1),1) + 'Cientos ' + dbo.F_Decenas(RIGHT(CONVERT(varchar,@Numero),2),1)

  WHEN @Numero between 500 AND 599 THEN 'Quinientos ' + dbo.F_Decenas(RIGHT(CONVERT(varchar, @Numero),2),1) + ' '

  WHEN @Numero between 600 AND 699 THEN 'Seiscientos ' + dbo.F_Decenas(RIGHT(CONVERT(varchar, @Numero),2),1) + ' '

  WHEN @Numero between 700 AND 799 THEN 'Setecientos ' + dbo.F_Decenas(RIGHT(CONVERT(varchar, @Numero),2),1) + ' '

  WHEN @Numero between 800 AND 899 THEN 'Ochocientos ' + dbo.F_Decenas(RIGHT(CONVERT(varchar, @Numero),2),1) + ' '

  WHEN @Numero between 900 AND 999 THEN 'Novecientos ' + dbo.F_Decenas(RIGHT(CONVERT(varchar, @Numero),2),1) + ' '

 END                     

 RETURN @Texto                     

END

GO

CREATE FUNCTION [dbo].[F_Millares](@Numero AS bigint, @Estilo AS bit=0)

RETURNS varchar(500)

AS                   

BEGIN

 DECLARE @Texto varchar(500)                   

 DECLARE @EstiloCentenas bit                   

 SELECT @EstiloCentenas=CONVERT(bit,LEN(@Numero)-4)                     

 SELECT @Texto=

  CASE                     

   WHEN @Numero=0000 THEN ' '

   WHEN @Numero>=1000 AND @Numero<2000 THEN 'Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=2000 AND @Numero<3000 THEN 'Dos Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=3000 AND @Numero<4000 THEN 'Tres Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=4000 AND @Numero<5000 THEN 'Cuatro Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=5000 AND @Numero<6000 THEN 'Cinco Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=6000 AND @Numero<7000 THEN 'Seis Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=7000 AND @Numero<8000 THEN 'Siete Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=8000 AND @Numero<9000 THEN 'Ocho Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=9000 AND @Numero<10000 THEN 'Nueve Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)

   WHEN @Numero>=2000 AND @Numero<1000000  

   THEN dbo.F_Centenas(LEFT(CONVERT(varchar, @Numero),LEN(@Numero)-3),                   

   @EstiloCentenas) + ' Mil ' + dbo.F_Centenas(RIGHT(CONVERT(varchar, @Numero),3),1)                  

   WHEN @Numero<1000 THEN dbo.F_Centenas(@Numero, @Estilo)

   WHEN @Numero<10 THEN dbo.F_Unidades(@Numero, 0)                 

   WHEN @Numero<100 THEN dbo.F_Decenas(@Numero, @Estilo)                 

   WHEN @Numero<1000 THEN dbo.F_Centenas(@Numero, @Estilo)                 

   END                     

 RETURN @Texto                     

END

GO

CREATE FUNCTION [dbo].[fn_RetornarNumeroEnLetras](@NumeroAProcesar AS VARCHAR(20),

@Moneda AS VARCHAR(30),

@CentavoNumerico INT)

RETURNS varchar(2000)

AS

BEGIN 

DECLARE @Numero bigint 

DECLARE @Decimal varchar(30) 

DECLARE @Texto varchar(500) 

DECLARE @EstiloMillares bit 


SELECT @Texto=''


--Obtenemos parte entera

IF patindex('%.%', @NumeroAProcesar)>0 

BEGIN 

SELECT @Numero=LEFT(@NumeroAProcesar, 

patindex('%.%', @NumeroAProcesar)-1) 

END 

ELSE 

BEGIN 

SELECT @Numero=CONVERT(bigint, @NumeroAProcesar) 

END 

SELECT @EstiloMillares=CONVERT(bit,LEN(@Numero)-7) 


--Proceso número negativos

IF @Numero<0 

BEGIN 

SELECT @Texto='menos ' 

SELECT @Numero=ABS(@Numero) 

END 


--Proceso parte entera

SELECT @Texto= @Texto + 

CASE 

WHEN @Numero=1000000 THEN 'Millon' 

WHEN @Numero>1000000 AND @Numero<1000000000000 

THEN dbo.F_Millares(LEFT(CONVERT(varchar, @Numero), LEN(@Numero)-6),@EstiloMillares) 

+ ' Millones ' 

+ dbo.F_Millares(RIGHT(CONVERT(varchar, @Numero), 6), 1)

WHEN @Numero<10 THEN dbo.F_Unidades(@Numero, 0) 

WHEN @Numero<100 THEN dbo.F_Decenas(@Numero, 1) 

WHEN @Numero<1000 THEN dbo.F_Centenas(@Numero, 1) 

WHEN @Numero<1000000 THEN dbo.F_Millares(@Numero, 1) 

END 


SELECT @Texto = @Texto + @Moneda + ' ' 


--Proceso parte decimal

IF patindex('%.%', @NumeroAProcesar) > 0 

BEGIN 

SELECT @Decimal= RIGHT(@NumeroAProcesar,LEN(@NumeroAProcesar)-patindex('%.%', @NumeroAProcesar))

SELECT @Numero = @Decimal

  IF @CentavoNumerico = 1

  BEGIN

SELECT @Texto= @Texto + 'Con ' + 

CASE 

WHEN @Numero=1000000 THEN 'Millon' 

WHEN @Numero>1000000 AND @Numero<1000000000000 

THEN dbo.F_Millares(LEFT(CONVERT(varchar, @Numero), LEN(@Numero)-6),@EstiloMillares) 

+' Millones '

+ dbo.F_Millares(RIGHT(CONVERT(varchar, @Numero), 6), 1)

WHEN @Numero<10 THEN dbo.F_Unidades(@Numero, 0) 

WHEN @Numero<100 THEN dbo.F_Decenas(@Numero, 1) 

WHEN @Numero<1000 THEN dbo.F_Centenas(@Numero, 1) 

WHEN @Numero<1000000 THEN dbo.F_Millares(@Numero, 1) 

END


SELECT @Texto = @Texto +

CASE 

WHEN LEN(@Decimal)=1 THEN ' Centavo ' 

WHEN LEN(@Decimal)=2 THEN ' Centavos ' 

WHEN LEN(@Decimal)=3 THEN ' Centavos ' 

END

END

ELSE IF @CentavoNumerico = 2

BEGIN

SELECT @Texto = @Texto + @Decimal + '/100 M. N.'

END

END

 

WHILE  CHARINDEX('  ',@Texto) <> 0

BEGIN

SELECT @Texto = REPLACE(@Texto,'  ',' ')

END

 

SELECT @Texto = REPLACE(@Texto,'Uno Millones','Un Millon') 

SELECT @Texto = REPLACE(@Texto,'Millones ' + @Moneda,'Millones de ' + @Moneda) 

IF @Moneda<>''

SELECT @Texto = REPLACE(@Texto,'Uno '+ @Moneda,'Un ' + @Moneda)

SELECT @Texto = REPLACE(@Texto,'Uno Centavos','Un Centavo')

RETURN @Texto 

END

GO


Select dbo.fn_RetornarNumeroEnLetras (193.13,'',1)

Uso del Try Catch vs manejo Global de excepciones

Mi regla es que debes usar el manejo de excepciones para casos específicos o "excepcionales". Un manejo global de excepciones debe...