0

I have a Scalar SQL function thats returns a decimal value, and this function is used in many stored procedures across my database. Now in some procedures, I need to set a value based on some criteria inside the function. To make it clearer, depending on some variables used in calculating the result of the function, I want to set another variable inside the Stored procedure, and return it to the client.

I don't want to change how the result is returned or the return type of the function. I am thinking of doing it by inserting the new value i want into an sql table and then reading it from the procedure, But is there another or better way to do it?

Thanks

3 Answers 3

2

No, you cannot. Functions are severely limited in SQL Server and do not allow any side effects.

What you can do, however, is convert your scalar function into a table function. In it, you can return a table with as many columns as you need, so returning more than one value is not a problem.

Sign up to request clarification or add additional context in comments.

Comments

1

You have a couple of options

1) Change it from a function to a stored procedure, and add an output parameter.

2) Change it from a scalar function to a table valued function returning a single row, with the additional value as an additional column.

If you need to preserve the existing function signature then just create a new table valued function that does the work (As per option 2 above), and modify your existing function to select from the new table valued function.

Here is some example code demonstrating this:

-- the original scalar function
CREATE FUNCTION dbo.t1(@param1 INT)
RETURNS INT AS
BEGIN
    RETURN @param1 + 1
END
GO

-- a new table valued function, that returns 2 values in a single row
CREATE FUNCTION dbo.t2(@param1 INT)
RETURNS TABLE AS
    RETURN (SELECT @param1 + 1 AS [r1], @param1 + 2 AS [r2])
GO

-- the modified original function, now selecting from the new table valued function
CREATE FUNCTION dbo.t3(@param1 INT)
RETURNS INT AS
BEGIN
    RETURN (SELECT r1 FROM dbo.t2(@param1))
END
GO

-- example usage
SELECT dbo.t1(1)
SELECT * FROM dbo.t2(1)
SELECT dbo.t3(1)

1 Comment

Thanks, I found that there was no other way than changing the function to a table valued function, since you cannot do any inserts or updates from within a function.
0

Table value functions that return a single row are my favorite technique when a single answer from a scalar function just isn't adequate (or slows the query too much). A table can have from zero to many rows. Once I realized a 'table' value function can be limited to returning only one row it became obvious that multiple questions that would require separate scalar functions can be accomplished in a single table value function. It's like a scalar function on steroids. I like to read in all needed data just once into an internal table variable, then manipulate that data assigning it to additional variables as needed, finally assembling the answers for the output 'table' of one record. My database environment is read only, not transaction based. Incredibly useful for large (Mult-TB) historical database like medical information. Frequently used to concatenate fields into an end user friendly 'sentence' to deal with data that can have zero to many values, like patient diagnosis. Outer Apply the table value function on filtered data and it is extremely efficient.

Comments

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.