1

I want to do create a function which would basically take float or integer values and convert to decimal of particular length and precision.

I have written the code below, but it seems CAST does not allow variable withing DECIMAL function :

CREATE OR ALTER FUNCTION dbo.DECI(@in as sql_variant,@len as int, @prec as int)
returns sql_variant
as
begin
     return CAST(@in as decimal(@len,@prec))
end
10
  • 5
    Simply put you can't do this, not in a function anyway. You could in a SP, using dynamic SQL, however, I suspect this is an XY Problem. What is the actual problem you're trying to solve here? Commented Nov 4, 2019 at 14:09
  • 1
    This can't be done in a function. You can't parameterize these properties of the decimal data type (as you've learned the hard way), so the only thing to do something that might work is to use dynamic SQL - but that can't be used in a function - it can only be used in a stored procedure. Commented Nov 4, 2019 at 14:10
  • The problem is that a function needs to return a known type, so the engine can correctly use the return meta-data to do checks and validations. This means that the scale and precision of the decimal (in this case) must be fixed. In an SP, you can response with a SELECT of multiple rows and columns, even if they vary over time or by the execution parameters. Commented Nov 4, 2019 at 14:12
  • 1
    It is technically possible to do this -- simply have a case statement enumerating every possible combination of length and precision. But it should be immediately obvious why this is not an attractive approach... and even when you've achieved "success" this way, you're still left with an SQL_VARIANT that you normally can't do anything with without explicit conversion, so you've gained nothing. Commented Nov 4, 2019 at 14:17
  • "The problem is that the function needs to return a known type" technically sql_variant is a "known" type, @EzLo, but using that data type has it own set of... Shall we say "features" related to it. Commented Nov 4, 2019 at 14:17

1 Answer 1

1

Implicit casting from SQL_VARIANT to most types (including DECIMAL) is not allowed, so you'll have to do explicit ones in most queries anyways

When you try to use this in (for example) in an INSERT statement

DECLARE @TestTable TABLE
(
    DecimalCol DECIMAL(3,2)
);

INSERT INTO @TestTable
(
    DecimalCol
)
VALUES
    (dbo.DECI(1.1, 3, 2))

You will face with the following error message:

Msg 257, Level 16, State 3, Line 44 Implicit conversion from data type sql_variant to decimal is not allowed. Use the CONVERT function to run this query.

Now, you'll have to update your query to:

INSERT INTO @TestTable
(
    DecimalCol
)
VALUES
    (CONVERT(DECIMAL(3,2), dbo.DECI(1.1, 3, 2)))

At this point, you did nothing, but a performance killer.

Do your stuff in the query directly:

INSERT INTO @TestTable
(
    DecimalCol
)
VALUES
    (CONVERT(DECIMAL(3,2), 1.1))
Sign up to request clarification or add additional context in comments.

6 Comments

This function has performance implications that are probably even more horrid than your average scalar-valued function, as bad as those already are, as this produces an enormous execution plan. (I haven't verified if SQL Server will even want to compile it, as the whole exercise seems pointless, but that's another concern.) That could be "fixed" by breaking the statement up, though.
@JeroenMostert It is pointless, I totally agree. There are much more problems with this code, than it solves, this is why I have the bold statement at the beginning.
Well, if you think the code is useless, why post in in the first place? even more so when that option have already been written and explained why it's bad in the comments to the question - so why bother posting it as an answer?
@ZoharPeled: First, that to show that it can indeed be done in this specific case. Then second, to point out how bad idea it is to do so.
IMHO, the last part of your answer is the only part that's worth keeping - showing why the OP had a bad / impractical / impossible idea is a good answer. Showing how to implement that bad / impractical idea is not - but then again, that's just my opinion - you don't have to agree with it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.