Converting Numbers to Words
 
In many business applications there is a need to convert a given number into its equivalent word. For example 39 would need to be converted as Thirty Nine. These sorts of conversions are used when application print invoices or cheques. I've seen many implementations of this logic in various languages like VB, FoxPro etc, but, what does it take to do a similar conversion in SQL Server?? Well, nothing much actually. Its very easy to write such a program in SQL Server and this article shows you how.

To keep the program small, I'm considering only two digit numbers (1..99) and only whole numbers. But you can extend this logic to handle fractional parts and also numbers greater than 99. Ofcourse the word that is generated is in English, but doing so for other languages should not be a problem. Here is the source for the same.


IF (OBJECT_ID('dbo.NumberToWords') IS NOT NULL)
	DROP PROCEDURE dbo.NumberToWords
GO
CREATE PROCEDURE dbo.NumberToWords
(
	@tnNumber	INT
) AS
BEGIN
	-- Make sure that we convert only for 1..99
	IF (@tnNumber < 1 OR @tnNumber > 99)
	BEGIN
		RAISERROR ('Invalid Number. Input must be between 1 and 99', 16, 1)
		RETURN
	END

	-- Start of logic.
	-- Declare some local variables
	DECLARE @numbersTable TABLE (number INT, word VARCHAR(10))
	DECLARE @outputString VARCHAR(8000)
	DECLARE @word VARCHAR(50)
	DECLARE @remainder INT
	DECLARE @counter INT

	-- Initialize the variables
	SET @outputString = ''
	SET @counter = 0

	-- Insert data for the numbers and words
	INSERT INTO @numbersTable VALUES (1, 'One')
	INSERT INTO @numbersTable VALUES (2, 'Two')
	INSERT INTO @numbersTable VALUES (3, 'Three')
	INSERT INTO @numbersTable VALUES (4, 'Four')
	INSERT INTO @numbersTable VALUES (5, 'Five')
	INSERT INTO @numbersTable VALUES (6, 'Six')
	INSERT INTO @numbersTable VALUES (7, 'Seven')
	INSERT INTO @numbersTable VALUES (8, 'Eight')
	INSERT INTO @numbersTable VALUES (9, 'Nine')
	INSERT INTO @numbersTable VALUES (10, 'Ten')
	INSERT INTO @numbersTable VALUES (11, 'Eleven')
	INSERT INTO @numbersTable VALUES (12, 'Twelve')
	INSERT INTO @numbersTable VALUES (13, 'Thirteen')
	INSERT INTO @numbersTable VALUES (14, 'Fourteen')
	INSERT INTO @numbersTable VALUES (15, 'Fifteen')
	INSERT INTO @numbersTable VALUES (16, 'Sixteen')
	INSERT INTO @numbersTable VALUES (17, 'Seventeen')
	INSERT INTO @numbersTable VALUES (18, 'Eighteen')
	INSERT INTO @numbersTable VALUES (19, 'Nineteen')
	INSERT INTO @numbersTable VALUES (20, 'Twenty')
	INSERT INTO @numbersTable VALUES (30, 'Thirty')
	INSERT INTO @numbersTable VALUES (40, 'Fourty')
	INSERT INTO @numbersTable VALUES (50, 'Fifty')
	INSERT INTO @numbersTable VALUES (60, 'Sixty')
	INSERT INTO @numbersTable VALUES (70, 'Seventy')
	INSERT INTO @numbersTable VALUES (80, 'Eighty')
	INSERT INTO @numbersTable VALUES (90, 'Ninenty')

	-- If the input number is < 20, we need some special processing
	IF (@tnNumber < 20)
	BEGIN
		SELECT @word = word FROM @numbersTable
			WHERE number = @tnNumber
		SET @outputString = @word
	END
	ELSE
	BEGIN
		WHILE (@tnNumber != 0)
		BEGIN
			-- Get the remainder of the result
			SET @remainder = (@tnNumber % 10) *
				CASE WHEN @counter = 0 THEN 1 ELSE @counter * 10 END
	
			-- Locate this value in our lookup table
			SELECT @word = word FROM @numbersTable
				WHERE number = @remainder
			SET @outputString = ISNULL(@word, '') + ' ' + @outputString
	
			-- Truncate the original number
			SET @tnNumber = @tnNumber / 10
			SET @counter = @counter + 1
		END
	END

	-- Print the result
	SELECT @outputString
END

The biggest chunk in the logic is the lookup table which has the words for the various numbers. If this was abstraced as a static table, then the code is hardly 10-20 lines long. The logic is also quite simple. We keep truncating the number till we reach 0 and for each iteration we do a modulo with 10 and obtain the remainder. This remainder is multiple with 10 to obtain the lookup value. This value is then searched in our lookup table and the string is formed. Finally, the string is printed. You can execute this procedure like this:


EXEC dbo.NumberToWords 56

Home