Technical Article

Format numeric values to language specific format

,

SQL Server returns numeric values always in a internal format. The conversion of numeric values
into a language specific format is usually part of the client. With this User Defined Function, you can do this
on your backend. The function expects 3 parameters: The numeric value, the requested language
and the number of decimals (will be rounded!). All parameters are described in more detail within
the function comment (header). Here're some calling examples:

SELECT dbo.fn_ConvertNumber(1500.555, 1031, 2) AS Example = 1.500,56    -- German
SELECT dbo.fn_ConvertNumber(1500.555, 2057, 2) AS Example = 1,500.56    -- Brit. English/American
SELECT dbo.fn_ConvertNumber(1500.555, 1036, 2) AS Example = 1 500,56    -- Spain, France


Please apologize my english, i'm not native speaker.
Thomas
www.sqlscripter.com

CREATE FUNCTION dbo.fn_ConvertNumber  (@dblValue FLOAT, 
				       @intLCID INT, 
				       @tintNoDecimals TINYINT)
RETURNS VARCHAR(50)


/*
	TSM, 02/07/2004,
	Visit: www.sqlscripter.com

	Description:
	------------
	This function converts a float value to a language specific
	numeric	format. The result is a converted varchar value.

	Parameter:
	----------

	@dblValue = Float value

	@intLCID = 
					  Result Example
					  --------------
	        1031  = Germany		  1.000,50
 	  	2057  = British English	  1,000.50
 		1033  = American	  1,000.50
 		1040  = Italian		  1.000,50
 		1036  = France		  1 000,50
 		1029  = Spain		  1 000,50

	@tintNoDecimals = Number of decimals


	Calling Examples: 	
	-----------------
	
	SELECT dbo.fn_ConvertNumber(1500.555, 1031, 2) AS Example = 1.500,56
	SELECT dbo.fn_ConvertNumber(1500.555, 2057, 2) AS Example = 1,500.56
	SELECT dbo.fn_ConvertNumber(1500.555, 1036, 2) AS Example = 1 500,56

*/

AS
BEGIN

   DECLARE 
	@strResult VARCHAR(50),
	@strTmp VARCHAR(50),
	@dbl FLOAT,
        @tintDecPos TINYINT,
        @tintNoOfThDel TINYINT,
        @strDecDelimiter CHAR(1),
	@strThDelimiter CHAR(1),
        @strDecValue VARCHAR(10),
        @strIntValue VARCHAR(40),
        @tintWhile TINYINT,
        @blnIsMinus BIT


   -- Defaults
   SET @tintWhile = 0
   SET @tintNoOfThDel = 0
   SET @blnIsMinus = 0    

   -- Read incoming value
   SET @dblValue = ISNULL(@dblValue, 0)

   -- Init negative value
   IF SIGN(@dblValue) < 0 
      SET @blnIsMinus = 1  -- We have a negative value

   -- Calculate and convert to string 
   SET @strResult = STR(@dblValue, 30, @tintNoDecimals)
   SET @strResult = LTRIM(RTRIM(@strResult))

   -- In case of a negative value, cut the "-"
   IF @blnIsMinus = 1 
      SET @strResult = SUBSTRING(@strResult, 2, LEN(@strResult) - 1)

   -- Init the requested format
   IF @intLCID = 1031 OR @intLCID = 1040 BEGIN
      -- Format: 1.000,50
      SET @strDecDelimiter = ','	-- Decimal Delimiter
      SET @strThDelimiter = '.'		-- Thousand Delimiter
   END

   IF @intLCID = 2057 OR @intLCID = 1033 BEGIN
      -- Format: 1,000.50
      SET @strDecDelimiter = '.'	-- Decimal Delimiter
      SET @strThDelimiter = ','		-- Thousand Delimiter
   END
  
   IF @intLCID = 1036 OR @intLCID = 1029 BEGIN
      -- Format: 1 000,50
      SET @strDecDelimiter = ','	-- Decimal Delimiter
      SET @strThDelimiter = ' '		-- Thousand Delimiter
   END

   -- Assign decimal delimiter format, 
   -- at this point, the internal delimiter is always '.'
   SET @strResult = REPLACE(@strResult, '.', @strDecDelimiter)

   -- Init the position of a possible decimal delimiter
   SET @tintDecPos = CHARINDEX(@strDecDelimiter, @strResult)

   -- Init the decimal and the main value
   IF @tintDecPos > 0 BEGIN
      -- Current value contains a decimal delimiter
      SET @strIntValue = SUBSTRING(@strResult, 1, @tintDecPos - 1)
      SET @strDecValue = SUBSTRING(@strResult, @tintDecPos + 1, LEN(@strResult)) 
   END
   ELSE BEGIN
      -- Current value contains no decimal delimiter
      SET @strIntValue = @strResult
      SET @strDecValue = REPLICATE('0', @tintNoDecimals)
   END

   -- String Handling
   SET @strTmp = ISNULL(LTRIM(RTRIM(@strIntValue)), '')
   SET @strIntValue = ''

   -- Init number of required thousand delimiter
   IF LEN(@strTmp) > 3 
      SET @tintNoOfThDel = (LEN(@strTmp) / 3)

   -- String conversion
   WHILE (@tintWhile < @tintNoOfThDel)
   BEGIN
  
      SET @tintWhile = @tintWhile + 1
  
      IF LEN(@strTmp) > 3
         SET @strIntValue = @strThDelimiter + RIGHT(@strTmp, 3) + @strIntValue
      ELSE
         SET @strIntValue = @strTmp + @strIntValue  
  
      SET @strTmp = LEFT(@strTmp, LEN(@strTmp) - 3)

   END

   -- Init final string
   SET @strIntValue = LEFT(@strTmp, LEN(@strTmp)) + @strIntValue

   -- Init decimal part
   IF @tintNoDecimals > 0
      SET @strResult = @strIntValue + @strDecDelimiter + @strDecValue
   ELSE
      SET @strResult = @strIntValue

   -- Handle negative values
   IF @blnIsMinus = 1 
      SET @strResult = '-' + @strResult

   -- Return
   RETURN (@strResult)


END



GO

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating