SideBar    Solution to CHECK Constraint Puzzle
DOWNLOAD THE CODE:
Download the Code 27051.zip

To populate the Calendar table with sample data, run the code that Listing 2 shows.

You can use the following code to modify the UDF that calculates working days. Here's how the body of the first set-based version should look:

ALTER FUNCTION dbo.fn_workdays
(@d1 AS datetime, @d2 AS datetime)
  RETURNS int
AS
BEGIN
RETURN(SELECT COUNT(*) FROM Calendar
WHERE cday BETWEEN @d1 AND @d2 AND day_type & 1 = 0)
END

To test this version, replace the function from Listing 1 with the one above, specifying ALTER FUNCTION instead of CREATE FUNCTION. The first set-based UDF version runs for 1 second on my laptop given the arguments '20000101', '39991231'.

If you have to work with a Calendar table and you don't have a way to distinguish between the different types of non-working days, you can use the DATEPART() function to determine which dates fall on weekends. Here's the body of a second set-based version of the UDF:

RETURN(SELECT COUNT(*) FROM Calendar
  WHERE cday BETWEEN @d1 AND @d2
    AND DATEPART(weekday, cday + @@DATEFIRST) NOT IN(1, 7))

Using the same arguments as in the previous tests, the second set-based UDF version runs for 2 seconds on my laptop.

If you don't have a Calendar table in your database but you do have an auxiliary table with a large sequence of integers such as the one that Listing 3 creates, you can use the following set-based UDF, which performs about as well as the second one:

-- Assuming an auxiliary table 
-- called Nums exists with a 
-- column called n
RETURN(SELECT COUNT(*) FROM Nums
  WHERE n <= DATEDIFF(day, @d1, @d2) + 1
    AND DATEPART(weekday,
(@d1+n-1) + @@DATEFIRST) NOT IN(1,7))

Now let's examine the single-expression approach to solving the problem.

Prev. page     1 2 [3] 4 5     next page



You must log on before posting a comment.

If you don't have a username & password, please register now.

 
 

ADS BY GOOGLE