| Author |
Topic |
|
Pinto
Aged Yak Warrior
590 Posts |
Posted - 2005-03-07 : 10:20:49
|
| Sorry for all these questions.... Has anyone an sp that will calculate the number of working days ? I will have a start date only and need to calculate 20 working days from that date. TIA |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2005-03-07 : 13:15:23
|
| search on "working days". There a several good posts discussing this. Most reasonable solutions involve keeping a permenant table that would hold all days and flag the holidays and work days for your culture. It's possible to do without that but the sql is MUCH easier with it.Be One with the OptimizerTG |
 |
|
|
Pinto
Aged Yak Warrior
590 Posts |
Posted - 2005-03-08 : 09:41:58
|
| I found this example but I cannot paste it into a stored procedure. The syntax is ok but I get an error when I try to save it. Error 21001 Stored procedure definition must include name and textCREATE FUNCTION fAddWorkingDay (@Start datetime, @NumOfDays integer)RETURNS datetimeASBEGINDECLARE @NextDay datetimeDECLARE @Counter intIF @NumOfDays>0 BEGINSET @Counter=1-- Drop the time part and initialize the Return VariableSET @NextDay=CONVERT(datetime ,(CONVERT(char(10),@Start,102)),102 )WHILE @Counter <= @NumOfDaysBEGINSET @NextDay = dbo.fNextWorkingDay(@NextDay)SET @Counter=@Counter+1ENDENDELSEBEGINSET @Counter=ABS(@NumOfDays)-- Drop the time part and initialize the Return VariableSET @NextDay=CONVERT(datetime ,(CONVERT(char(10),@Start,102)),102 )WHILE @Counter>0BEGINSET @NextDay = dbo.fPreviousWorkingDay(@NextDay)SET @Counter=@Counter-1ENDENDRETURN @NextDayEND |
 |
|
|
Xerxes
Aged Yak Warrior
666 Posts |
Posted - 2005-03-08 : 09:45:08
|
It appears that you're attempting to turn a user-defined function into a stored procedure. Your error occurs because you're saying CREATE FUNCTION. Replace CREATE FUNCTION with CREATE PROCEDURE!Semper fi, XERXES, USMC(Ret.)------------------------------------------------------The Marine Corps taught me everything but SQL! |
 |
|
|
Bustaz Kool
Master Smack Fu Yak Hacker
1834 Posts |
Posted - 2005-03-08 : 18:28:35
|
| You'll need to change the RETURN, also. You could pass @NextDay in as another parameter and mark it as an "OUTPUT" type.HTH=================================================================In order to improve the mind, we ought less to learn than to contemplate.-Rene Descartes, philosopher and mathematician (1596-1650) |
 |
|
|
Xerxes
Aged Yak Warrior
666 Posts |
Posted - 2005-03-09 : 09:37:48
|
quote: Originally posted by Bustaz Kool You'll need to change the RETURN, also. You could pass @NextDay in as another parameter and mark it as an "OUTPUT" type.HTH=================================================================In order to improve the mind, we ought less to learn than to contemplate.-Rene Descartes, philosopher and mathematician (1596-1650)
Great idea, Steve! Wish I'd thought of that! Semper fi, XERXES, USMC(Ret.)------------------------------------------------------The Marine Corps taught me everything but SQL! |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2005-03-09 : 10:03:15
|
| That function looks pretty bad -- I wouldn't use it. I'll post one in a few minutes for you. but, as mentioned, if you want to exclude holidays and such, you'll need a more sophisticated method and also a table of dates to exclude.- Jeff |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2005-03-09 : 10:10:22
|
this lets you go backwards and forwards. seems to work fine, and it has no loops. check it out.Create function NextWorkDay(@CurrDate datetime, @DaysToAdd int)returns datetimeasbegin declare @WeeksToAdd int; declare @dw int; set @WeeksToAdd = (@DaysToAdd / 5) * 7 set @DaysToAdd = @DaysToAdd % 5 set @CurrDate = DateAdd(dd,@WeeksToAdd + @DaysToAdd, @CurrDate) set @dw = datepart(dw,@CurrDate) if sign(@DaysToAdd) < 0 begin if @dw = 1 set @CurrDate = @CurrDate - 2 if @dw = 7 set @CurrDate = @CurrDate - 1 end else begin if @dw = 1 set @CurrDate = @CurrDate + 1 if @dw = 7 set @CurrDate = @CurrDate + 2 endreturn @CurrDAteend if you only need to go forward (i.e., DaysToAdd will always be positive) you can simplify that last IF condition.Note: The function assumes that the starting date you specify will be a week day. - Jeff |
 |
|
|
bluecjh
Starting Member
7 Posts |
Posted - 2005-03-11 : 07:08:43
|
| functions to return 'working days' tend to fall into2 categories, either set based using a calendar table which marksweekends and public holidaysor a loop based approach examining each day and deciding if it is working day etc...If you're looking for the nth working day then if n is large the set based approach isquicker, if n is small a loop can be much quicker.Chris |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2005-03-12 : 00:45:37
|
| Can't you use a TALLY table to avoid the loop?Kristen |
 |
|
|
groston
Yak Posting Veteran
61 Posts |
Posted - 2005-03-14 : 14:55:00
|
Here is a similar function that I just wrote. Note that the table Holiday contains a list of all business-specified holidays. This function returns true if @CurDate is within @DayNum business days of the beginning of the month.ALTER FUNCTION dbo.udf_BusinessDayOfMonth ( @CurDate datetime, -- must be passed in since UDF's cannot have getdate calls @DayNum int -- check for which business day )RETURNS bitAS BEGIN DECLARE @CurMonth int DECLARE @CheckDay datetime DECLARE @IsHoliday int DECLARE @RetVal bit SET @RetVal = 0 SET @CheckDay = @CurDate SET @CurMonth = datepart (month, @CurDate) WHILE @DayNum > 0 BEGIN SET @CheckDay = dateadd (day, -1, @CheckDay) if datepart (month, @CheckDay) <> @CurMonth begin SET @RetVal = 1 break end else begin SELECT @IsHoliday = count(*) FROM Holiday WHERE Holidate = @CheckDay if not (@IsHoliday = 1 OR datepart (weekday, @CheckDay) = 1 OR datepart (weekday, @CheckDay) = 7) SET @DayNum = @DayNum - 1 end END RETURN @RetVal END |
 |
|
|
|