June 28, 2016 at 3:36 pm
I have a function that I use to compute the number of days that a patient is unavailable in order to reduce the number of days they have breached a waiting times deadline.
The function is as follows:
CREATE FUNCTION [dbo].[GetDaysUnavailable]
(
@intRefint
)
RETURNS int
AS
BEGIN
DECLARE @ReturnValueint
DECLARE @dtUnavailFromdatetime
DECLARE @dtUnavailTodatetime
DECLARE @dtRefRcvddatetime
SELECT @dtUnavailFrom = UnavailableFrom FROM Referrals WHERE ReferralID = @intRef
SELECT @dtUnavailTo = UnavailableTo FROM Referrals WHERE ReferralID = @intRef
SELECT @dtRefRcvd = ReferralReceivedDate FROM Referrals WHERE ReferralID = @intRef
IF ISNULL(@dtUnavailFrom,'') = '' OR ISNULL(@dtUnavailTo,'') = ''
BEGIN
SELECT @ReturnValue = 0
END
ELSE
BEGIN
IF @dtRefRcvd > @dtUnavailFrom
BEGIN
SELECT @ReturnValue = DATEDIFF(day,@dtRefRcvd, @dtUnavailTo)
END
ELSE
BEGIN
SELECT @ReturnValue = DATEDIFF(day,@dtUnavailFrom, @dtUnavailTo)
END
END
RETURN @ReturnValue
END
As you can see it works out the difference between the date that the person is unavailable to and either the date they are unavailable from or the date their referral was received. This was fine using my original structure whereby the 2 date fields were in the main table. The problem with this was that there could only ever be 1 period of unavailability.
I have now changed the table structure so that the unavailability periods are in their own table which has a 1-to-many relationship with the main table.
But now I can't figure out how to get my function to cope withe new structure. I basically need to be able to pull every row in the unavailability table that relates to the parent record and them loop through each row, summing up the unavailability and returning the total at the end.
Any ideas?
June 28, 2016 at 3:42 pm
1) Is there a question here?
2) ALWAYS use WITH SCHEMABINDING when using UDFs, views and any dang thing else you can use it with! Build a box around the user, and in this case the user is all developers. Oh, it also prevents a nasty table spool for Halloween protection on UPDATEs.
3) NEVER EVER EVER use Scalar (that touch data) or Multi-statement Table Valued Functions if you can help it!!! They are HORRIBLY HORRIBLY BAD!! Inline the logic, or convert to an Inline Table Valued Function.
Best,
Kevin G. Boles
SQL Server Consultant
SQL MVP 2007-2012
TheSQLGuru on googles mail service
June 28, 2016 at 3:44 pm
1. Sorry, I jumped the gun with my post. The full question is now there.
2. What do you mean by build a box around the user and what is Halloween protection? I'm not performing any UPDATE in the function so I fail to see the relevance.
3. What do you mean by inline the logic or convert to an inline table valued function? My function only returns a single integer value.
June 28, 2016 at 6:33 pm
NHS Baz (6/28/2016)
3. What do you mean by inline the logic or convert to an inline table valued function? My function only returns a single integer value.
Please see the following article where that question is answered and demonstrated.
[font="Arial Black"]How to Make Scalar UDFs Run Faster (SQL Spackle)[/font][/url]
--Jeff Moden
Change is inevitable... Change for the better is not.
June 28, 2016 at 6:44 pm
NHS Baz (6/28/2016)
2. What do you mean by build a box around the user and what is Halloween protection? I'm not performing any UPDATE in the function so I fail to see the relevance.
In many cases, especially when a function references a table, using WITH SCHEMABINDING frequently eliminates an extra "Spool", whether an UPDATE occurs or not. From what I've seen, that's not so true with iTFVs (inline Table Valued Functions) but others may have observed otherwise. A fellow by the name of Paul White wrote an article on the subject and can be found at the following URL.
http://sqlperformance.com/2013/02/sql-plan/halloween-problem-part-4
As for me, I almost always never say always, if I can help it, because there are almost always exceptions.:-P
--Jeff Moden
Change is inevitable... Change for the better is not.
June 28, 2016 at 7:50 pm
As for me, I almost always never say always, if I can help it, because there are almost always exceptions.:-P
Which is why I said "if you can help it" about never. 😎
Best,
Kevin G. Boles
SQL Server Consultant
SQL MVP 2007-2012
TheSQLGuru on googles mail service
June 28, 2016 at 8:02 pm
TheSQLGuru (6/28/2016)
As for me, I almost always never say always, if I can help it, because there are almost always exceptions.:-P
Which is why I said "if you can help it" about never. 😎
😉
--Jeff Moden
Change is inevitable... Change for the better is not.
June 29, 2016 at 3:25 am
Thanks for the input folks but does anyone have an answer to the question that was actaully posed in the original post?
June 29, 2016 at 8:05 am
NHS Baz (6/29/2016)
Thanks for the input folks but does anyone have an answer to the question that was actaully posed in the original post?
Think set-based 😉
CREATE FUNCTION [dbo].[GetDaysUnavailable]
(
@intRefint
)
RETURNS TABLE
AS
RETURN
SELECT SUM(CASE WHEN ReferralReceivedDate > UnavailableFrom
THEN DATEDIFF(day,ReferralReceivedDate, UnavailableTo)
ELSE DATEDIFF(day,UnavailableFrom, UnavailableTo) END) AS ReturnValue
FROM Referrals
WHERE ReferralID = @intRef;
June 29, 2016 at 10:34 am
NHS Baz (6/29/2016)
Thanks for the input folks but does anyone have an answer to the question that was actaully posed in the original post?
It would be nice to have some sample data and expected output so we can test possible solutions.
Best,
Kevin G. Boles
SQL Server Consultant
SQL MVP 2007-2012
TheSQLGuru on googles mail service
Viewing 10 posts - 1 through 10 (of 10 total)
You must be logged in to reply to this topic. Login to reply