You could just cast it to the appropriate data type? (Or better still, store it as the appropriate data type):
SELECT v,
AsDecimal = CAST(v AS DECIMAL(3, 2))
FROM (VALUES ('4.2'), ('4.80'), ('2.43'), ('2.45')) t (v)
Will give:
v AsDecimal
4.2 4.20
4.80 4.80
2.43 2.43
2.45 2.45
If this is not an option you can use:
SELECT v,
AsDecimal = CAST(v AS DECIMAL(4, 2)),
AsVarchar = CASE WHEN CHARINDEX('.', v) = 0 THEN v + '.00'
WHEN CHARINDEX('.', REVERSE(v)) > 3 THEN SUBSTRING(v, 1, CHARINDEX('.', v) + 2)
ELSE v + REPLICATE('0', 3 - CHARINDEX('.', REVERSE(v)))
END
FROM (VALUES ('4.2'), ('4.80'), ('2.43'), ('2.45'), ('54'), ('4.001'), ('35.051')) t (v);
Which gives:
v AsDecimal AsVarchar
4.2 4.20 4.20
4.80 4.80 4.80
2.43 2.43 2.43
2.45 2.45 2.45
54 54.00 54.00
4.001 4.00 4.00
35.051 35.05 35.05
Finally, if you have non varchar values you need to check the conversion first with ISNUMERIC, but this has its flaws:
SELECT v,
AsDecimal = CASE WHEN ISNUMERIC(v) = 1 THEN CAST(v AS DECIMAL(4, 2)) END,
AsVarchar = CASE WHEN ISNUMERIC(v) = 0 THEN v
WHEN CHARINDEX('.', v) = 0 THEN v + '.00'
WHEN CHARINDEX('.', REVERSE(v)) > 3 THEN SUBSTRING(v, 1, CHARINDEX('.', v) + 2)
ELSE v + REPLICATE('0', 3 - CHARINDEX('.', REVERSE(v)))
END,
SQLServer2012 = TRY_CONVERT(DECIMAL(4, 2), v)
FROM (VALUES ('4.2'), ('4.80'), ('2.43'), ('2.45'), ('54'), ('4.001'), ('35.051'), ('fail')) t (v);
Which gives:
v AsDecimal AsVarchar SQLServer2012
4.2 4.20 4.20 4.20
4.80 4.80 4.80 4.80
2.43 2.43 2.43 2.43
2.45 2.45 2.45 2.45
54 54.00 54.00 54.00
4.001 4.00 4.00 4.00
35.051 35.05 35.05 35.05
fail NULL fail NULL