Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-11-23 : 10:00:25
|
Dear all,I'm a little/lot stuck on an issue I really need help on.I have created a script that works but, a script that creates far more records than I've asked for and, when I've checked the script WHILE statements, I cannot for the life of me work out why it is failing.It is supposed to use a cursor to look at a load of "Timesheet" records and, on each one, depending on how many hours there are in a single timesheet and how many hours per day someone works, create individual timesheets for each day - ensuring that the next date in series is a workday.If the date of the timesheet is 07/09/2009 (7th September) that has 13 days on it, it is supposed to know that it requires 13 timesheets at 7.5 hours per timesheet. It knows this from a column (numrecords) on the absenceview table then it is supposed to create the following records.07/09/200908/09/200909/09/200910/09/200911/09/200914/09/200915/09/200916/09/200917/09/200918/09/200921/09/200922/09/200923/09/2009but instead, it does the first pass as above and then does:21/09/200922/09/200923/09/200914/09/200915/09/200916/09/200917/09/200918/09/200907/09/200908/09/200909/09/200910/09/200911/09/2009and then repeats the first pass yet again.Does anyone have any ideas why?--DROP TABLE dbo.AbsencesIF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND TABLE_NAME='Absences') DROP TABLE Absences ELSEcreate table Absences( TimeDate DateTime, MonthNum varchar(2), YearNum varchar(4), ResourceName varchar(max), Studio_Company varchar(max), ChargeDesc varchar(max), AbHrs float, );-- Populate with dataDECLARE @AbDate DatetimeDECLARE @AbsenceHours FloatDECLARE @LastRec FloatDECLARE @RecCounter IntDECLARE @Looper IntDECLARE @AdjustDay IntDECLARE @DateCheck varchar(2)DECLARE @curTimeDate DateTimeDECLARE @curResourceName varchar(max)DECLARE @curChargeDesc varchar(max)DECLARE @curAbsenceHours realDECLARE @Time_ID int/*Create cursor to look at every record in Absenceview */DECLARE @absence_cursor CURSOR SET @absence_cursor = CURSOR FOR SELECT TimeDate, ResourceName, ChargeDesc, AbHrs, TS_ID FROM dbo.AbsenceviewOPEN @absence_cursorFETCH NEXT FROM @absence_cursor INTO @curTimeDate, @curResourceName, @curChargeDesc, @curAbsenceHours, @Time_ID WHILE @@FETCH_STATUS = 0BEGIN IF ((SELECT NumRecords FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID) = 1) BEGIN---- This is what happens when there is only one Absence timesheet. It is to create a single-- absence record as it is in the Absenceview without additional records created.-- INSERT INTO Absences ( TimeDate, MonthNum, YearNum, ResourceName, Studio_Company, ChargeDesc, AbHrs ) ( SELECT TimeDate, MonthNum, YearNum, ResourceName, Studio_Company, ChargeDesc, AbHrs FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID );END ELSE BEGIN---- For multi-record creation -- SET @AbsenceHours =(( SELECT Hours_pw FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID) / ( SELECT Days_pw FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID)) SET @RecCounter = ( SELECT NumRecords FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID) SET @AdjustDay = 0 SET @DateCheck = 'N'-- Change value of @AbsenceHours if dbo.Absenceview.AbHrs is negative IF ( SELECT AbHrs FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID ) < 0 BEGIN SET @AbsenceHours = 0 - @AbsenceHours END---- This is to check if the hours of LAST timesheet is <= full day hours.-- @LastRec will either be the same as @AbsenceHours or less.-- -- If exact match found, set @LastRec same as @AbsenceHours IF (( SELECT AbHrs FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID ) / @AbsenceHours = @RecCounter) BEGIN SET @LastRec = @AbsenceHours END ELSE BEGIN -- If fraction match found, set @LastRec as remainder of @AbsenceHours SET @LastRec = (@RecCounter - (( SELECT AbHrs FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID)) / @AbsenceHours) * @AbsenceHours END---- Set the first Date. This will be the date the timesheet was entered-- SET @Looper = 1 SET @AbDate = ( SELECT TimeDate FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID)---- This is to create additional required records but also, check the proposed date-- against the dbo.calendar and increment the date, if necessary, to ensure the new-- record contains the date of a valid working day.-- WHILE @Looper <= (@RecCounter-1) BEGIN INSERT INTO Absences ( TimeDate, MonthNum, YearNum, ResourceName, Studio_Company, ChargeDesc, AbHrs ) (SELECT @AbDate, MONTH(@AbDate), YEAR (@AbDate), ResourceName, Studio_Company, ChargeDesc, @AbsenceHours FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID );-- Check the next date to see if it is a valid WorkDay by looking up proposed date in dbo.Calendar-- SET @abDate = ( SELECT TOP (1)caldate FROM dbo.Calendar WHERE caldate > @abDate AND workingday = 'Y') SET @Looper = @Looper + 1 END---- Once the first sets of Absence records have been created with the value of @AbsenceHours,-- the last timesheet to create will be created with the value of @LastRec--- INSERT INTO Absences ( TimeDate, MonthNum, YearNum, ResourceName, Studio_Company, ChargeDesc, AbHrs ) ( SELECT @AbDate, MONTH(@AbDate), YEAR(@AbDate), ResourceName, Studio_Company, ChargeDesc, @LastRec FROM dbo.Absenceview WHERE TimeDate = @curTimeDate AND ResourceName = @curResourceName AND ChargeDesc = @curChargeDesc AND AbHrs = @curAbsenceHours AND TS_ID = @Time_ID )ENDFETCH NEXT FROM @absence_cursor INTO @curTimeDate, @curResourceName, @curChargeDesc, @curAbsenceHours, @Time_ID ENDCLOSE @absence_cursorDEALLOCATE @absence_cursor |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2009-11-23 : 11:43:04
|
| you dont need cursor for this. also dont post in script library. this forum is for working scriptscan you illustrate what you need with sample data and output? |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-11-23 : 12:07:59
|
| sorry I posted in here, is there a way of moving this?Sample dataRecord_ID: 00001TimeDate 07/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 97.50 hours (this is calculated and displayed in 'AbsenceView' from resource working hours records)Output13 individual timesheets in a new tableRecord: 001TimeDate 07/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 002TimeDate 08/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 003TimeDate 09/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 004TimeDate 10/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursWhat the script does is create the records based upon the contents on the selected row and, ensures that the date it uses for the new timesheet is valid. I have a 'WorkingDays' table with Y or N next to all dates from 2007-2012. This is so I can flag National or company Holidays as well as Saturdays and Sundays.Hope it makes sense, sorry again for posting in the wrong place.Matt |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2009-11-23 : 12:48:01
|
| so u basically needs to split the absencehours into multiples of 7.5 based on working day from calendar? |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-11-24 : 03:56:49
|
| Correct. The script that I created works but, with errors. I want to create a table's worth of static data which is created from a Timesheets table. Unfortunately, the data is an export from a 4D system so I don't have any control on how the data is originally created and so I'm using an SQL database system to create the MI reporting dashboard for a SharePoint site.One point, sometimes someone will request 4.5 days holiday and so, I have made my original script deal with the last record creation as a fraction of a day - by assigning a figure to the @LastRec variable which will either be a full day or a fraction of one. Hope this makes sense.Kind RegardsMatt |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-11-25 : 03:59:58
|
| I still haven't worked out an alternative to using cursor or WHILE statement to get this script to work. I know the calculations of what it does is correct, it just executes it too many times.thanks |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-11-27 : 08:34:53
|
| Hi,Anyone got any ideas how I can resolve this issue? Have no idea what to do next after working for a week creating the script in the first place - I cannot see any logical reason why this script is creating more records than I require.It knows from variable @NumRecords how may loops to do with exception to the last record which it does using a different routine before it finishes. After it finishes, it goes to fetch NEXT CURSOR and restarts the process for the next timesheet record.Can anyone see anything in the script that would make it process the same row multiple times but a decrementing number of new instances and from a different starting place on each?Thanks |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-11-30 : 05:19:11
|
| Hi all,Does anyone have any script that they would run which creates a set of records in a table based upon the contents of another table on a line by line basis? Still need this issue to be resolved and have no hope of doing it by myself, I'm a bit lost in it.Thanks |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2009-11-30 : 09:59:36
|
quote: Originally posted by mattlightbourn Hi all,Does anyone have any script that they would run which creates a set of records in a table based upon the contents of another table on a line by line basis? Still need this issue to be resolved and have no hope of doing it by myself, I'm a bit lost in it.Thanks
you can create records based on another table by using a count table. can you illustrate your scenario in below format in which case somebody will be able to provide you more help. |
 |
|
|
mattlightbourn
Starting Member
37 Posts |
Posted - 2009-12-01 : 06:10:22
|
| Thanks for your reply, I have a NumRecords column in the source Timesheets table which is to be used to stop a variable from incrementing in a WHILE loop when it reaches the desired number of record creation.Sample dataRecord_ID: 00001TimeDate 07/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 97.50 hours (this is calculated and displayed in 'AbsenceView' from resource working hours records)NumRecords: 13 (pre calculated)Output13 individual timesheets in a new tableRecord: 001TimeDate 07/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 002TimeDate 08/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 003TimeDate 09/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 004TimeDate 10/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 005TimeDate 11/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 006TimeDate 14/09/09 (notice here it has found that 12th and 13th are weekends - my script for finding this using WorkCal works)ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursRecord: 007TimeDate 15/09/09ResourceName Joe BloggsChargeDesc: AbsenceAbsenceHours: 7.50 hoursAnd so on for 8, 9, 10, 11, 12, 13Thanks for your helpKind RegardsMatt |
 |
|
|
|
|
|
|
|