VARCHAR to DECIMAL

前端 未结 12 666
清歌不尽
清歌不尽 2020-12-06 09:24

I want to convert a varchar(max) column to decimal(10,4).

When I try to use cast or convert I am getting an arit

12条回答
  •  鱼传尺愫
    2020-12-06 09:59

    I came up with the following solution:

    SELECT [Str], DecimalParsed = CASE 
    WHEN ISNUMERIC([Str]) = 1 AND CHARINDEX('.', [Str])=0 AND LEN(REPLACE(REPLACE([Str], '-', ''), '+', '')) < 29 THEN CONVERT(decimal(38,10), [Str])
    WHEN ISNUMERIC([Str]) = 1 AND (CHARINDEX('.', [Str])!=0 AND CHARINDEX('.', REPLACE(REPLACE([Str], '-', ''), '+', ''))<=29) THEN 
        CONVERT(decimal(38,10), 
                CASE WHEN LEN([Str]) - LEN(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([Str], '0', ''), '1', ''), '2', ''), '3', ''), '4', ''), '5', ''), '6', ''), '7', ''), '8', ''), '9', '')) <= 38 
                     THEN [Str] 
                     ELSE SUBSTRING([Str], 1, 38 + LEN(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([Str], '0', ''), '1', ''), '2', ''), '3', ''), '4', ''), '5', ''), '6', ''), '7', ''), '8', ''), '9', ''))) END)
    ELSE NULL END
    FROM TestStrToDecimal
    

    I know it looks like an overkill and probably it is, but it works for me (checked both positive, negative, big and small numbers of different precision and scale - everything is converted to decimal(38,10) or NULL).

    It is hard-coded to decimal(38,10) type, so if you need different precision, change the constants in the code (38, 10, 29).

    How it works? The result is:

    • if conversion is simple without overflow or precision loss (e.g. 123 or 123.456), then it just convert it.
    • if number is not too big, but has too many digits after decimal point (e.g. 123.1234567890123456789012345678901234567890), then it trims the exceeding digits at the end keeping only 38 first digits.
    • if number is too big and can't be converted to decimal without an overflow (e.g. 9876543210987654321098765432109876543210), then NULL is returned

    each case is separate WHEN statement inthe code above.

    Here are few examples of conversion: enter image description here

提交回复
热议问题