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.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 A script that creates too many records

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/2009
08/09/2009
09/09/2009
10/09/2009
11/09/2009
14/09/2009
15/09/2009
16/09/2009
17/09/2009
18/09/2009
21/09/2009
22/09/2009
23/09/2009

but instead, it does the first pass as above and then does:

21/09/2009
22/09/2009
23/09/2009

14/09/2009
15/09/2009
16/09/2009
17/09/2009
18/09/2009

07/09/2009
08/09/2009
09/09/2009
10/09/2009
11/09/2009

and then repeats the first pass yet again.

Does anyone have any ideas why?



--DROP TABLE dbo.Absences

IF EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE'
AND TABLE_NAME='Absences')
DROP TABLE Absences
ELSE

create table Absences(
TimeDate DateTime,
MonthNum varchar(2),
YearNum varchar(4),
ResourceName varchar(max),
Studio_Company varchar(max),
ChargeDesc varchar(max),
AbHrs float,
);

-- Populate with data

DECLARE @AbDate Datetime
DECLARE @AbsenceHours Float
DECLARE @LastRec Float
DECLARE @RecCounter Int
DECLARE @Looper Int
DECLARE @AdjustDay Int
DECLARE @DateCheck varchar(2)

DECLARE @curTimeDate DateTime
DECLARE @curResourceName varchar(max)
DECLARE @curChargeDesc varchar(max)
DECLARE @curAbsenceHours real
DECLARE @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.Absenceview

OPEN @absence_cursor

FETCH NEXT FROM @absence_cursor
INTO @curTimeDate,
@curResourceName,
@curChargeDesc,
@curAbsenceHours,
@Time_ID

WHILE @@FETCH_STATUS = 0
BEGIN
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 )
END
FETCH NEXT FROM @absence_cursor
INTO @curTimeDate,
@curResourceName,
@curChargeDesc,
@curAbsenceHours,
@Time_ID
END

CLOSE @absence_cursor

DEALLOCATE @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 scripts

can you illustrate what you need with sample data and output?
Go to Top of Page

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 data

Record_ID: 00001
TimeDate 07/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 97.50 hours (this is calculated and displayed in 'AbsenceView' from resource working hours records)

Output

13 individual timesheets in a new table

Record: 001
TimeDate 07/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 002
TimeDate 08/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 003
TimeDate 09/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 004
TimeDate 10/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

What 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
Go to Top of Page

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?
Go to Top of Page

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 Regards

Matt
Go to Top of Page

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
Go to Top of Page

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
Go to Top of Page

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
Go to Top of Page

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.
Go to Top of Page

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 data

Record_ID: 00001
TimeDate 07/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 97.50 hours (this is calculated and displayed in 'AbsenceView' from resource working hours records)
NumRecords: 13 (pre calculated)

Output

13 individual timesheets in a new table

Record: 001
TimeDate 07/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 002
TimeDate 08/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 003
TimeDate 09/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 004
TimeDate 10/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 005
TimeDate 11/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 006
TimeDate 14/09/09 (notice here it has found that 12th and 13th are weekends - my script for finding this using WorkCal works)
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

Record: 007
TimeDate 15/09/09
ResourceName Joe Bloggs
ChargeDesc: Absence
AbsenceHours: 7.50 hours

And so on for 8, 9, 10, 11, 12, 13


Thanks for your help

Kind Regards

Matt
Go to Top of Page
   

- Advertisement -