How can I create a function in SQL with 2 parameters? - sql

I'm trying to create a function that SUMs the total number of minutes of actual duration for videos with a Finished status given a UserID as a parameter. This is what I have so far but I can't figure out how to add the parameter for the Finished status. This comes from a different table of Status that has a StatusID and StatusText. Or would I do a NOT NULL statement?
CREATE FUNCTION dbo.vc_VideoRunTime(#userID int)
RETURNS int AS
BEGIN
DECLARE #returnValue int
SELECT #returnValue = DATEDIFF (n, StartDateTime, EndDateTime) FROM vc_Video
WHERE vc_Video.vc_UserID = #userID
RETURN #returnValue
END
GO

If your finished status is represented as a NULL endtime, then your function is fine:
CREATE FUNCTION dbo.vc_VideoRunTime (
#userID int
)
RETURNS int AS
BEGIN
DECLARE #returnValue int;
SELECT #returnValue = SUM(DATEDIFF(minute, v.StartDateTime, v.EndDateTime))
FROM vc_Video v
WHERE v.vc_UserID = #userID ;
RETURN #returnValue;
END;
GO
Why? The DATEDIFF() will return NULL if either argument is NULL. The SUM() will then return NULL.
Note that I changed the n to minute. This is much more readable. (I don't know anyone who uses the "n" option for "minute", it makes me think "nanosecond".)
If you actually want the function to return 0 in this case, then use COALESCE():
RETURN COALESCE(#returnValue, 0);

Related

Why I cannot get a result value from T-SQL function

I'm trying to learn function in SQL Server, and I don't know why I cannot get a proper result from a T-SQL function.
The query what creates function is:
CREATE FUNCTION yuri_func1
(#valDate VARCHAR(10))
RETURNS VARCHAR
AS
BEGIN
DECLARE #valWeekday VARCHAR(10);
SET #valWeekday = DATENAME(WEEKDAY, #valDate);
RETURN #valWeekday;
END
And the other query is
select dbo.yuri_func1('2017-12-29') as [요일]
but the only result I got is just
Blank. (="")
But when I executed function like this,
select DATENAME(WEEKDAY, '2017-12-29')
the result was
MONDAY
I still don't get that why they return different results.
Does anybody know why?
This is because you should be accepting DateTime as a parameter in your function and not varchar
create Function yuri_func1 (#valDate DateTime) --Wrong parameter type
RETURN VARCHAR(10) -- No proper sizing of return type
AS
BEGIN
declare #valWeekday varCHAR(10);
Set #valWeekday = DATENAME(WEEKDAY,#valDate);
return #valWeekday;
END
GO

Finding whether the passed value is greater than zero or not using SQL functiom

I wrote a user defined function which takes price as input parameter and returns if the input is greater than zero or not.
https://stackoverflow.com/editing-help
I have tried as follows.
create function fn_GreateCheck(#value int)
returns varchar(20)
as
begin
select case
when #value >0 then 'Greater'
when #value <0 then 'Lesser'
end
return #value
end
Please help me on this
Thanks.
Try something like this:
create function dbo.fn_GreateCheck(#value int)
returns varchar(20)
as
begin
declare #ret VARCHAR(20) = (case
when #value >0 then 'Greater'
when #value <0 then 'Lesser'
else 'Zero'
end)
return #ret
end
GO
select dbo.fn_GreateCheck (1000) --> Greater
select dbo.fn_GreateCheck (-10) --> Lesser
select dbo.fn_GreateCheck (0) --> Zero
select dbo.fn_GreateCheck (NULL) --> Zero
GO
A user defined function cannot return data to the client, so you have to catch the result in a variable and return the value. To return a result set, you have to define Table-value user defined function.

user defined function call vs calling UDF in a Store procedure

I have a user defined function that is called inside a stored procedure. All that stored procedure does is return the value that is obtained from the UDF scalar function.
However,
Select * UDF_FunctionName(param1,param2)
udf call is here-
SELECT dbo.udfFunction('1234',10) as result
and
Exec StoreProcName(param1,param2)
are returning different results.
StoreProcName calls the `UDF_FunctionName(param1,param2)
sproc code is here-
BEGIN
SET NOCOUNT ON;
Return SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
END
What could be the reason for different results?.
You are trying to use RETURN and SELECT together:
Return SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
You cannot do that, you either want to return the result, or select it. Depending on which you choose, retrieving the value will differ.
If you do this:
SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
Then the resultset will have a single row and column containing your value. Access this exactly as you would any other resultset.
If you do this:
RETURN [DbName].[dbo].[udfFunction](#param1, #param2)
Your stored procedure will have a return value which is the result of your function call. Access this by defining a scalar variable and assigning it to the result of the SP call - assuming the result is INT that might look like
DECLARE #result INT
EXEC #Result = StoredProcName(#param1, #param2)
You should not use RETURN in this way in a stored procedure. If you want to return a scalar value to the calling code use an OUTPUT parameter. RETURN is generally used for status codes.
You might have something like
-- SAMPLE UDF
CREATE FUNCTION dbo.YourUDF (#Username VARCHAR(30), #EntityID INT)
RETURNS INT
AS
BEGIN
RETURN #EntityID;
END
GO
-- SAMPLE PROCEDURE
CREATE PROCEDURE dbo.YourProc #Username VARCHAR(30), #EntityID INT, #Output INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET #Output = dbo.YourUDF(#Username, #EntityID);
IF #Output IS NULL -- AN ERROR
BEGIN
RETURN 1; -- RETURN A STATUS OF -1 TO INDICATE ERROR
END
END
Then you could call this as:
DECLARE #Output INT, #ReturnValue INT;
EXECUTE #ReturnValue = dbo.YourProc
#Username = '1234',
#EntityID = 1,
#Output = #Output OUTPUT;
SELECT ValueFromUDF = #Output,
ReturnValue = #ReturnValue;
This returns:
ValueFromUDF ReturnValue
------------------------------
1 0
If we pass NULL as #EntityID, to trigger the artificial error, then we get a return status of -1:
DECLARE #Output INT, #ReturnValue INT;
EXECUTE #ReturnValue = dbo.YourProc
#Username = '1234',
#EntityID = NULL,
#Output = #Output OUTPUT;
SELECT ValueFromUDF = #Output,
ReturnValue = #ReturnValue;
ValueFromUDF ReturnValue
------------------------------
NULL 1

If a value contains a certain character then do this or else do this

I am trying to write a function which processes a column value and returns the value with everything before the '#' symbol.
I have managed to do this so far by using the following code:
Create Function fnStaffCodeConvert (#staffcode varchar(10))
Returns varchar(4)
AS
BEGIN
DECLARE #staffinitals varchar(4)
SET #staffinitals = (SELECT substring(#staffcode,0, CHARINDEX('#',#staffcode)))
Return #staffinitials
END
Example result from function - Parameter in = ABC#123, Returns = ABC.
This works but then exclusively returns every result where the column contained an # value and the remaining results without the # are omitted. I.e. ABC#123 returns ABC but XYZ does not return anything.
How can I amend the code to give me both sets of values? I imagine I would have to put an 'IF' statement in there but I am unsure how to write it to get the results I want.
Many thanks in advance :)
Mike
You are almost there:
ALTER FUNCTION fnStaffCodeConvert (#staffcode varchar(10))
RETURNS VARCHAR(4)
AS
BEGIN
DECLARE #staffinitals AS VARCHAR(4)
if CHARINDEX('#',#staffcode) <> 0
SET #staffinitals = (SELECT substring(#staffcode,0, CHARINDEX('#',#staffcode)))
Else
SET #staffinitals = #staffcode
RETURN #staffinitals
END
You can do what you want with a case:
Create Function fnStaffCodeConvert (#staffcode varchar(10))
Returns varchar(4);
AS
BEGIN
DECLARE #staffinitals varchar(4);
SET #staffinitals = (SELECT (case when #staffcode like '%#%'
then substring(#staffcode,0, CHARINDEX('#',#staffcode)
else #staffcode
end));
Return #staffinitials;
END
But wait, you can simplify this further:
Create Function fnStaffCodeConvert (#staffcode varchar(10))
Returns varchar(4)
AS
BEGIN
DECLARE #staffinitals varchar(4)
SELECT #staffinitials = (case when #staffcode like '%#%'
then substring(#staffcode,0, CHARINDEX('#',#staffcode)
else #staffcode
end);
Return #staffinitials;
END;

creating function using newID()

I keep getting this error: Any Ideas?
Invalid use of side-effecting or time-dependent operator in 'newid' within a function.
I am working with MS-SQL Server 2005. Here is the T-SQL statement:
Create Function [dbo].[GetNewNumber]( )
RETURNS int
AS
BEGIN
Declare #code int
set #code = (SELECT CAST(CAST(newid() AS binary(3)) AS int) )
RETURN (#code)
END
You can't use NEWID() within a function.
A usual workaround (in my experience, it's more been the need for GETDATE()) is to have to pass it in:
Create Function [dbo].[GetNewNumber](#newid UNIQUEIDENTIFIER )
RETURNS int
AS
BEGIN
Declare #code int
set #code = (SELECT CAST(CAST(#newid AS binary(3)) AS int) )
RETURN (#code)
END
And call it like:
SELECT dbo.GetNewNumber(NEWID())
The function will not let you use the NewID, but this can be worked around.
Create View vwGetNewNumber
as
Select Cast(Cast(newid() AS binary(3)) AS int) as NextID
Create Function [dbo].[GetNewNumber] ( ) RETURNS int
AS
BEGIN
Declare #code int
Select top 1 #code=NextID from vwGetNewNumber
RETURN (#code)
END
Then you can use select dbo.[GetNewNumber]() as planned.
Does this have to be done with a function call? Whenever I needs this functionality, I just use:
checksum(newid())
This will generate negative numbers -- if they must be positive, you could use
abs(checksum(newid()))