Alter a SQL server function to accept new optional parameter - sql

I already have a function in SQL Server 2005 as:
ALTER function [dbo].[fCalculateEstimateDate] (#vWorkOrderID numeric)
Returns varchar(100) AS
Begin
<Function Body>
End
I want to modify this function to accept addition optional parameter #ToDate. I am going to add logic in function if #Todate Provided then do something else continue with existing code.
I modified the function as:
ALTER function [dbo].[fCalculateEstimateDate] (#vWorkOrderID numeric,#ToDate DateTime=null)
Returns varchar(100) AS
Begin
<Function Body>
End
Now I can call function as:
SELECT dbo.fCalculateEstimateDate(647,GETDATE())
But it gives error on following call:
SELECT dbo.fCalculateEstimateDate(647)
as
An insufficient number of arguments were supplied for the procedure or
function dbo.fCalculateEstimateDate.
which as per my understanding should not happen.
Am I missing anything?

From CREATE FUNCTION:
When a parameter of the function has a default value, the keyword DEFAULT must be specified when the function is called to retrieve the default value. This behavior is different from using parameters with default values in stored procedures in which omitting the parameter also implies the default value.
So you need to do:
SELECT dbo.fCalculateEstimateDate(647,DEFAULT)

The way to keep SELECT dbo.fCalculateEstimateDate(647) call working is:
ALTER function [dbo].[fCalculateEstimateDate] (#vWorkOrderID numeric)
Returns varchar(100) AS
Declare #Result varchar(100)
SELECT #Result = [dbo].[fCalculateEstimateDate_v2] (#vWorkOrderID,DEFAULT)
Return #Result
Begin
End
CREATE function [dbo].[fCalculateEstimateDate_v2] (#vWorkOrderID numeric,#ToDate DateTime=null)
Returns varchar(100) AS
Begin
<Function Body>
End

I have found the EXECUTE command as suggested here T-SQL - function with default parameters to work well. With this approach there is no 'DEFAULT' needed when calling the function, you just omit the parameter as you would with a stored procedure.

Related

Linked Table Valued Function Parameters (SQL Server)

I need to create a SQL Server TVF that takes a single param and then used that param to build the other required parameters. Is this even possible?
The error states incorrect syntax near 'LEFT'. Simple representation below.
CREATE FUNCTION TESTFUNCTION
(
-- Add the parameters for the function here
#PRM1 VARCHAR(2) = 'ABC',
#PRM2 VARCHAR(1) = LEFT(#PRM1,1)
)
RETURNS TABLE
AS
RETURN
(
-- Add the SELECT statement with parameter references here
SELECT #PRM2
)
GO
Thank You!
BEFORE EDIT MADE IN THE QUESTION :
You need only one parameters :
SELECT #PRM2 = LEFT(#PRM1, 1);
However, you need scaler function not table valued function :
CREATE FUNCTION TESTFUNCTION
(
-- Add the parameters for the function here
#PRM1 VARCHAR(2) = 'ABC'
)
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE #PRM2 VARCHAR(255)
SET #PRM2 = LEFT(#PRM1, 1)
RETURNS (#PRM2)
END
Note : Your #PRM1 will accept only two characters which are AB. So, define appropriate length.

is not a recognized built-in function name

Created a function
CREATE FUNCTION Split_On_Upper_Case(#Temp VARCHAR(1000))
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE #KeepValues AS VARCHAR(50)
SET #KeepValues='%[^ ][A-Z]%'
WHILE PATINDEX(#KeepValues COLLATE Latin1_General_Bin,#Temp)>0
SET #Temp=STUFF(#Temp,PATINDEX(#KeepValues COLLATE Latin1_General_Bin,#Temp)+1,0,' ')
RETURN #Temp
END
When iam trying to exexute this SELECT Split_On_Upper_Case('SaiBharath') It gives an error "'Split_On_Upper_Case' is not a recognized built-in function name.".Can someone please explain this
Add [dbo] in prefix and then execute as same :
SELECT [dbo].[Split_On_Upper_Case] ('SaiBharath')
To execute function in sql, prefix dbo should be used.
SELECT [dbo].[Split_On_Upper_Case] ('SaiBharath')
Just to make sure, set the database you created your function on first by using the use clause and then prefix the call of your function with dbo.
USE <DatabaseName>
SELECT dbo.Split_On_Upper_Case('camelCase')
Also, a good practice is prefixing each function or database object for that matter, with its schema name.

How can you get the number of parameters

How can i get the number of parameters that weree given to a MS SQL function or stored procedure?
Lets say mu function is:
CREATE FUNCTION dbo.tst
(
#idINT ,
#StartDate DATETIME ,
#EndDate DATETIME
)
...
When i call the function using SELECT dbo.tst(1, '2015-11-11 23:14:45') is there a way to determine that the function was called with only two parameters?
Edit:
Idealy I would like to have a funtion/sp that can coop with an unknow number of parameters, but as far as I know this is not possible.
The idea was to create a funtion with lets say 20 params and discover (count) the number of params passed into the function, so we can process only the values that were actually given to the funtion.
The bigger picture is implementing a hash funtion voor Data Vault 2.0 to create a hash value per record to discover changes. Since every table has a different number of fields, this can be chalanging. You do not want to create a funtion per table...
I hope this makes sense.
First of all with function like:
CREATE FUNCTION dbo.tst(
#idINT ,
#StartDate DATETIME ,
#EndDate DATETIME)
SELECT dbo.tst(1, '2015-11-11 23:14:45')
You will get:
error An insufficient number of arguments were supplied for the
procedure or function dbo.tst.
One way is to add default parameter value like:
CREATE FUNCTION dbo.tst(
#id INT,
#StartDate DATETIME = NULL,
#EndDate DATETIME = NULL)
but still you need to call it as:
SELECT dbo.tst(1, '2015-11-11 23:14:45', default)
with scalar function you can call it as:
EXECUTE dbo.tst 1, '2015-11-11 23:14:45'
I guess you want something like overloaded function in other programming languages. With functions you always need to specify all parameters.
With stored procedures you can use:
CREATE PROCEDURE dbo.tst(
#idINT ,
#StartDate DATETIME = NULL,
#EndDate DATETIME = NULL)
AS
BEGIN
IF #StartDate IS NULL
-- user does not provide start date use default or do some operations
-- SET #StartDate = ...
...
IF #EndDate IS NULL
...
END;
Then you can reason about it:
EXEC dbo.tst 1, NULL, NULL
will be the same as:
EXEC dbo.tst 1
More info: CREATE FUNCTION:
When a parameter of the function has a default value, the keyword
DEFAULT must be specified when the function is called to retrieve the
default value. This behavior is different from using parameters with
default values in stored procedures in which omitting the parameter
also implies the default value. However, the DEFAULT keyword is not
required when invoking a scalar function by using the EXECUTE
statement.

SQL Server parameterized SELECT procedure returns no result, but returns records when set explicitly

I'm having problems with the following procedure
CREATE PROCEDURE [dbo].[Q2_05] (#Ch1 nvarchar, #Ch4 nvarchar, #globalOptionCode nvarchar)
AS
BEGIN
SET NOCOUNT ON;
SELECT [2_05].Ch1, [2_05].Ch4, [2_05].GlobalOption, [2_05].Part, [2_05].[Key]
FROM [dbo.NV300Autostructure].[2_05]
WHERE ((([2_05].Ch1)=#Ch1) AND (([2_05].Ch4)=#Ch4) AND (([2_05].GlobalOption)=#globalOptionCode));
END
when I execute it with the following parameters ('5', 'TH', '.') it returns no results, but in the process of elimination I found that modifying the conditions line and set [2_05].Ch4 explicitly to 'TH' like so:
WHERE ((([2_05].Ch1)=#Ch1) AND (([2_05].Ch4)='TH') AND (([2_05].GlobalOption)=#globalOptionCode));
it returns a row of the database. Why is that happening?
You are not specifying a size for your nvarchar parameters. The default is 1 character.
So the procedure is testing for [2_05].Ch4)='T' when you use the parameters.

How to call a scalar-valued from with a stored procedure

say I have a scalar-valued function with takes two Guids as parameters:
dbo.CarDistribution
The two Guids area ModelId and AreaId.
The function returns another Guid.
Could someone please explain to me how I call this function within a stored procedure and set the result returned to a variable.
I tried calling it with:
CarDistribution('a Guid in here', 'another Guid in here')
but I get the error
'Incorrect syntax near 'speciesareapresence_eval_internal''
Thanks!
declare #NewGUID uniqueidentifier
Select #NewGUID = dbo.CarDistribution (ModelId, AreaId)
From dbo.YourTable