Technical Article

Convert Numeric Figures into Words

,

Hi guys
    What about a function that converts a number figure into words.This sample script is to demonstrate the procedural capabilities of SQL Server .
Samples  select fig2words(10) will give --Ten-- ,select fig2words(103) will give --one hundred and three --
    The author uses much under utilized capability of SQL Server the recursive function calls to implement this inherently recursive logic many will raise their eyebrows and will complain about performance issues, dont worry ,no problem at all my warranty is there.
    This function uses a base table named  units_table ,as described  after the script ,pl create this table and populate it with the subsequent statement. Now you can go for the creation of the function, just replace the user name here "john" with your session user name.
    Recursive logic is very clear and author dont want to put even his name as comment in order not to disturb the free flow of the logic

How about including this in standard convert function !!!

Have nice time

Regards John

See Rezvan modifications down the code

CREATE  FUNCTION fig2words
(@FigInNum int)
returns varchar(255)
as
begin

declare @numUnit int
declare @numUnitKount int
declare @remainder int
declare @figInWords varchar(255)

set @numUnit=(select max(num_unit) from units_table where num_unit <= @FigInNum )

if @FigInNum  <=0 
begin
set @figInWords=''
return(@figInWords)
end

if @numUnit= @FigInNum  
begin
set @figInWords=(select InWords from units_table where num_unit = @FigInNum )
return (@figInWords)
end

if @numUnit >=100 
begin

set @numUnitKount=@FigInNum/@numUnit
set @remainder=@FigInNum%@numUnit
set @figInWords=john.fig2words(@numUnitKount) + ' ' +  john.fig2words (@numUnit)
  + ' ' + case
  when @remainder <=0 then ''  
  when @remainder < 100 then 'and ' + john.fig2words(@remainder)
  else john.fig2words(@remainder)
  end
return(@figInWords)
end
else
begin
set @remainder=@FigInNum-@numUnit
set @figInWords=john.fig2words(@numUnit) + ' ' + john.fig2words(@remainder)
return(@figInWords)
end

return(@figInWords)

end

go


create table units_table
(
num_unit int primary key,
InWords varchar(255)
)
go


insert into 
units_table
SELECT 0,'zero'
UNION ALL 
SELECT 1,'one'
UNION ALL 
SELECT 2,'two'
UNION ALL 
SELECT 3,'three'
UNION ALL 
SELECT 4,'four'
UNION ALL 
SELECT 5,'five'
UNION ALL 
SELECT 6,'six'
UNION ALL 
SELECT 7,'seven'
UNION ALL 
SELECT 8,'eight'
UNION ALL 
SELECT 9,'nine'
UNION ALL 
SELECT 10,'ten'
UNION ALL 
SELECT 11,'eleven'
UNION ALL 
SELECT 12,'twelve'
UNION ALL 
SELECT 13,'thirteen'
UNION ALL 
SELECT 14,'fourteen'
UNION ALL 
SELECT 15,'fifteen'
UNION ALL 
SELECT 16,'sixteen'
UNION ALL 
SELECT 17,'seventeen'
UNION ALL 
SELECT 18,'eighteen'
UNION ALL 
SELECT 19,'nineteen'
UNION ALL 
SELECT 20,'twenty'
UNION ALL 
SELECT 30,'thirty'
UNION ALL 
SELECT 40,'fourty'
UNION ALL 
SELECT 50,'fifty'
UNION ALL 
SELECT 60,'sixty'
UNION ALL 
SELECT 70,'seventy'
UNION ALL 
SELECT 80,'eighty'
UNION ALL 
SELECT 90,'ninety'
UNION ALL 
SELECT 100,'hundred'
UNION ALL 
SELECT 1000,'thousand'
UNION ALL 
SELECT 1000000,'million'
UNION ALL 
SELECT 1000000000,'billion'

Rezvans Modified version 

"Razvan Socol" <rsocol@fx.ro>

I tried your script for converting numeric figures into words and it seems good. I have a few suggestions:
1. You should prefix negative numbers with "minus"
2. You should return "zero" for 0.
3. For figures like 200000 or 1500000 you should remove the extra space between "hundred" and "thousand" 
(now it returns: "one million five hundred  thousand")
4. For 100 (or 1000, etc) you should return "one hundred" instead of "hundred".

Here is how I would do it:
 
ALTER FUNCTION fig2words (@FigInNum int) RETURNS varchar(255) AS
BEGIN
 
 DECLARE @numUnit int
 DECLARE @numUnitKount int
 DECLARE @remainder int
 DECLARE @figInWords varchar(255)
 
 IF @FigInNum<0 BEGIN
  SET @figInWords='minus '+dbo.fig2words(- @FigInNum)
  RETURN @figInWords
 END
 
 SELECT @numUnit=MAX(num_unit) FROM units_table WHERE num_unit <= @FigInNum
 
 IF @numUnit=@FigInNum BEGIN
  SELECT @figInWords=CASE WHEN @FigInNum>=100 THEN 'one ' ELSE '' END
   + InWords FROM units_table WHERE num_unit = @FigInNum
  RETURN @figInWords
 END
 
 IF @numUnit >=100 BEGIN
 
  SET @numUnitKount=@FigInNum/@numUnit
  SET @remainder=@FigInNum%@numUnit
 
  SELECT @figInWords=dbo.fig2words(@numUnitKount) + ' ' + InWords 
   FROM units_table WHERE num_unit = @numUnit
 
  IF @remainder>0 
   SET @figInWords = @figInWords
     + CASE WHEN @remainder<100 THEN ' and ' ELSE ' ' END
    + dbo.fig2words(@remainder)
 
 END
 ELSE BEGIN
  SET @remainder=@FigInNum-@numUnit 
  SET @figInWords=dbo.fig2words(@numUnit)
  IF @remainder>0 
   SET @figInWords = @figInWords + ' ' + dbo.fig2words(@remainder)
 END
 
 RETURN(@figInWords)
 
END

It is a little less readable, but I think that it gives better results.
 
The performance is good, but not very good. It takes 7 seconds on a 366MHz system to run the following:
SELECT Quantity*UnitPrice, dbo.fig2words(Quantity*UnitPrice) FROM Northwind.dbo.[Order Details]

That table has 2155 rows. It's not that my computer is too slow, because
SELECT Quantity*UnitPrice FROM Northwind.dbo.[Order Details]
only takes 13 miliseconds.
But I must recognize that this function will usualy be executed for only one row, and in this case it's fast enough (less than 20 miliseconds).
 
Razvan

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating