Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Stored Procedure Assistance

Status
Not open for further replies.

ChewDoggie

Programmer
Joined
Mar 14, 2005
Messages
604
Location
US
Hello All,

I've written a stored procedure that almost works.....I think. :-)

I use "FETCH NEXT FROM <cursor>" syntax b/c I don't know of another way to accomplish what I want.

THe problem is that when I execute the "DECLARE AssocHours_Cursor CURSOR FOR SELECT..." statement, the "SET @HrsRows = @@ROWCOUNT" statement only returns ONE row. But the same statement in SSMS returns 19 rows.

Here's my code:
Code:
USE [HRConnect]
GO
/****** Object:  StoredProcedure [dbo].[Attendances_GetForAssociate1]    Script Date: 01/05/2010 15:43:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		ChewDOGGIE
-- Create date: 
-- Description:	
-- =============================================
ALTER PROCEDURE [dbo].[Attendances_GetForAssociate1] 
	-- Add the parameters for the stored procedure here
	@inAssociateGUID		UniqueIdentifier
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;
	DECLARE @AH_SD date
	DECLARE @AH_ED date
	DECLARE @AH_TH decimal(6,2)
	DECLARE @AH_CH decimal(6,2)
	DECLARE @DD_SD date
	DECLARE @DD_ED date
	DECLARE @DD Integer
	DECLARE @HrsRows Integer
	DECLARE @DiffRows Integer
	DECLARE @AddDays Integer
	DECLARE @RowNum Integer
	DECLARE @CalcHours Decimal(6,2)
	DECLARE @DropDate date
	DECLARE @Points decimal(6,2)
	DECLARE @AttGUID uniqueidentifier
	DECLARE @RGUID uniqueidentifier
	DECLARE @Comments nvarchar(60)
	DECLARE @Reason nvarchar(60)
		
    -- Insert statements for procedure here	
    CREATE TABLE #OutPut (StartDate date, EndDate date, TotalHours decimal(6,2), CalculatedHours decimal(6,2), DropOffDate date, AttendanceGUID uniqueidentifier, AssociateGUID uniqueidentifier, ReasonCode nvarchar(30), ReasonGUID uniqueidentifier, Comments nvarchar(50))
    DECLARE AssocHours_Cursor CURSOR FOR SELECT AttendanceGUID, AttendanceStartDate, AttendanceEndDate, TotalHours, CalculatedHours, Comments, R.ReasonGUID, R.ReasonCode from tblAttendance INNER JOIN tblReasons as R on tblAttendance.ReasonGUID = R.ReasonGUID WHERE AssociateGUID = @inAssociateGUID and TotalHours > 0 order by AttendanceStartDate
	SET @HrsRows = @@ROWCOUNT
	DECLARE DiffDates_Cursor CURSOR FOR SELECT AttendanceStartDate, AttendanceEndDate, DATEDIFF("D", AttendanceStartDate, AttendanceEndDate) AS DiffDays FROM tblAttendance WHERE AssociateGUID = @inAssociateGUID and DATEDIFF("D", AttendanceStartDate, AttendanceEndDate) > 5 ORDER BY AttendanceStartDate
	SET @DiffRows = @@ROWCOUNT
	OPEN AssocHours_Cursor
	OPEN DiffDates_Cursor
	While @HrsRows > 0
		BEGIN
		FETCH NEXT FROM AssocHours_Cursor INTO @AttGUID, @AH_SD, @AH_ED, @AH_TH, @AH_CH, @Comments, @RGUID, @Reason
		SET @AddDays = 364
		SET @RowNum = 0
		while @RowNum <= @DiffRows		
			BEGIN
			FETCH NEXT FROM DiffDates_Cursor INTO @DD_SD, @DD_ED, @DD
			IF (@DD_SD > @AH_SD AND @DD_SD <= DATEADD("D", @DD, @AH_SD))
				BEGIN
				SET @AddDays = @AddDays + @DD
				END
			SET @RowNum = @RowNum + 1				
			END
		SET @CalcHours = 0
		IF (DATEDIFF("D", GETDATE(), @AH_SD) > @AddDays)
			SET @CalcHours = @AH_TH
		IF (@CalcHours = 0)
			SET @Points = 0
		ELSE IF (@CalcHours < 2)
			SET @Points = 0.25
		ELSE IF (@CalcHours < 4)
			SET @Points = 0.50
		ELSE IF (@CalcHours < 6)
			SET @Points = 0.75
		ELSE IF (@CalcHours < 7.99)
			SET @Points = 1
		ELSE
			SET @Points = @CalcHours / (8 * 1)
		SET @DropDate = DATEADD("D", @AddDays, @AH_SD)
		--update tblAttendance set AttendanceStartDate = @AH_SD, AttendanceEndDate = @AH_ED, 
		INSERT INTO #OutPut VALUES(@AH_SD, @AH_ED, @AH_TH, @CalcHours, @DropDate, @AttGUID, @inAssociateGUID, @Reason, @RGUID, @Comments)
		SET @HrsRows = @HrsRows - 1
		END
	SELECT * FROM #OutPut
END

99% of my SP experience is with simple queries and updates. This is my second attempt at something that involves significant overhead.

If there's a better way, lay it on me.

Thanks !

Chew

10% of your life is what happens to you. 90% of your life is how you deal with it.
 
Can you please explain in English what this code is supposed to do?

I suspect it can be written as a simple one statement insert command, but I have hard time understanding the logic.
 
It's complicated, but in short, I'm analyzing an employee attendance record and applying business rules/logic and writing the results to an output table.

First I want to select records into a TempTable #1 with this SELECT statement:

Code:
SELECT AttendanceGUID, AttendanceStartDate, AttendanceEndDate, TotalHours, CalculatedHours, Comments, R.ReasonGUID, R.ReasonCode from tblAttendance INNER JOIN tblReasons as R on tblAttendance.ReasonGUID = R.ReasonGUID WHERE AssociateGUID = @inAssociateGUID and TotalHours > 0 order by AttendanceStartDate

Then I want to select records into TempTable #2 with this SELECT statement:

Code:
SELECT AttendanceStartDate, AttendanceEndDate, DATEDIFF("D", AttendanceStartDate, AttendanceEndDate) AS DiffDays FROM tblAttendance WHERE AssociateGUID = @inAssociateGUID and DATEDIFF("D", AttendanceStartDate, AttendanceEndDate) > 5 ORDER BY AttendanceStartDate

THen I want to do a nested loop of the two result sets (While loops), the TempTable #2 INSIDE of the TempTable #1, perform some processing and ADD A RECORD to a NEW table called "#OutPut". Like this:

Code:
    While @HrsRows > 0        
		BEGIN        
		FETCH NEXT FROM AssocHours_Cursor INTO @AttGUID, @AH_SD, @AH_ED, @AH_TH, @AH_CH, @Comments, @RGUID, @Reason
		SET @AddDays = 364
		SET @RowNum = 0
		while @RowNum <= @DiffRows
			BEGIN
			FETCH NEXT FROM DiffDates_Cursor INTO @DD_SD, @DD_ED, @DD
			IF (@DD_SD > @AH_SD AND @DD_SD <= DATEADD("D", @DD, @AH_SD))
				BEGIN
				SET @AddDays = @AddDays + @DD
				END
			SET @RowNum = @RowNum + 1
			END
		SET @CalcHours = 0
		IF (DATEDIFF("D", GETDATE(), @AH_SD) > @AddDays)
			SET @CalcHours = @AH_TH
		IF (@CalcHours = 0)
			SET @Points = 0
		ELSE IF (@CalcHours < 2)
			SET @Points = 0.25
		ELSE IF (@CalcHours < 4)
			SET @Points = 0.50
		ELSE IF (@CalcHours < 6)
			SET @Points = 0.75
		ELSE IF (@CalcHours < 7.99)
			SET @Points = 1
		ELSE            
			SET @Points = @CalcHours / (8 * 1)
		SET @DropDate = DATEADD("D", @AddDays, @AH_SD)
		INSERT INTO #OutPut VALUES(@AH_SD, @AH_ED, @AH_TH, @CalcHours, @DropDate, @AttGUID, @inAssociateGUID, @Reason, @RGUID, @Comments)
		SET @HrsRows = @HrsRows - 1
		END

Then return everything from the #OutPut Table. If there's a better way to accomplish this, I'm all ears. And again, the issue I'm having is the @@ROWCOUNT isn't returning the correct number of rows.

Hope that's clearer.

Chew

10% of your life is what happens to you. 90% of your life is how you deal with it.
 
ALSO, I just realized that I need to reset the cursor to the first record in the INSIDE while loop (while @RowNum <= @DiffRows) AFTER exiting the INSIDE LOOP. Additionally, I need to close/destroy the cursors after I'm done.

10% of your life is what happens to you. 90% of your life is how you deal with it.
 
I don't think you need loops at all. In the worse case scenario you can create a scalar function that would return Points depending on your dates and then insert into the new table with only one select statement.

Try working in this direction - I think you're making the task more complex than it needs to be.
 
Can you post some sample data from the 2 tables involved and then also show the expected output. It'll go a long way towards understanding your process, and helping you achieve your goals.

-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Yes, I'll post some sample data. But keep in mind that the business rules that are implemented by HR are extremely complicated, so much so, that I don't know if I can adequately explain them here. But I will say this much as I've already written this code in VBA (b/c they're currently tracking attendance in an Excel Spreadsheet):

Every time an employee attendance record is added, the entire history of the employee must be analyzed to determine, what effect, if any, will the new record have on previous records. Points are earned for absences and tardies. Points are suppose to drop off after one year (default dropoff period), but the dropoff period can be extended if they employee takes FMLA/Military leaves of absence greater than 5 days (extended by the amount of time off).

...like I said, it's complicated.

So, this is what I'm doing. Like I said above, I've already built this logic into an Excel Spreadsheet (I believe George helped me with getting the code to run -- I had to put the file in a 'Trusted location'). That code has been tested and is verified to be correct. But now I'm building the same logic into a C# .NET desktop app and I'm trying to re-create the logic in a SQL Server SP.

But here's some data from the 1st Query:

AttendanceGUID AttendanceStartDate AttendanceEndDate TotalHours CalculatedHours Comments ReasonGUID ReasonCode
B960E425-72F9-45D2-A18C-698DDF33AB14 2007-06-27 2007-06-27 6.00 0.00 Absent EFF4C88B-7F59-4FC9-B9C8-94BFF633265D Absent
A615245D-D593-4595-A8E5-7FC694629713 2007-10-18 2007-10-18 8.00 0.00 Absent EFF4C88B-7F59-4FC9-B9C8-94BFF633265D Absent
485041EF-142F-4F60-BC9B-988BB656C469 2008-02-05 2008-02-29 192.00 0.00 LOA to 2/29/2008 06A66546-A64A-4AAD-B296-50DB8D292053 LOA
BF24002E-8168-4295-B383-F2378D1A7C6D 2008-03-05 2008-03-05 8.00 0.00 FMLA Denied F08D1A30-6C20-4340-939C-E4C79A92755D FMLA Leave
87EBCCF2-A9B5-43FC-8F72-6301E593D9E2 2008-03-11 2008-03-13 16.00 0.00 FMLA Denied (3/11 - 3/12) w/ Dr. Note F08D1A30-6C20-4340-939C-E4C79A92755D FMLA Leave

Here's some sample data from the 2nd query:

AttendanceStartDate AttendanceEndDate DiffDays
2008-02-05 2008-02-29 24

But markros was correct, I could create a function to calculate points but I still have to return the ENTIRE employee history to be stored in a dataset and displayed in a DataGridView control.

HTH

Chew



10% of your life is what happens to you. 90% of your life is how you deal with it.
 
Stored procedure can return multiple resultsets which would be accessible from .NET application.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top