Click here to Skip to main content
15,891,745 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi All ,

I am trying to use a cursor and its showing error The variable does not currently have a cursor allocated to it even though its allocated . Any help will be really appreciated . Thanks in advance .

What I have tried:

SQL
<pre>DECLARE @firstday1 Date = null,
	@Lastday1 Date = null,
	@RequestType1 nvarchar = null,
	@EmployeeIdRequest1 int = null


SELECT @firstday1 = FORMAT(PeriodFrom,'yyyy-MM-dd') , @Lastday1 = FORMAT(PeriodTo,'yyyy-MM-dd') ,@RequestType1 = TRIM(RequestType),@EmployeeIdRequest1 = EmployeeID  FROM MST_TBL_Approvalrequests WHERE Autoid = 	@ApprovalReqID;


 DECLARE @Enumerator1 CURSOR 
		SET @Enumerator1 = CURSOR  FAST_FORWARD FOR
				 with dates_CTE1 (date) as (
						select @firstday1 
						Union ALL
						select DATEADD(day, 1, date)
						from dates_CTE1
						where date < @Lastday1
						)	
				select  date  FROM dates_CTE1
				OPTION (maxrecursion 365);
		OPEN @Enumerator1
		DECLARE @LoopDate1 date
	
		WHILE (1=1)
				BEGIN
					FETCH NEXT FROM @Enumerator1 into @LoopDate1	
						IF (@@FETCH_STATUS <> 0) break

	   BEGIN
	   if exists(SELECT AutoId from PPMS_TBL_AttendanceMaster where FORMAT(date,'yyyy-MM-dd')=@LoopDate1 and EmployeeID = @EmployeeIdRequest1 )            
       BEGIN 
        UPDATE PPA SET 
             PPA.PresentStatus = case when (MSTA.RequestTypeID = 10 and PPA.PresentStatus ='Work From Home') then 'Work From Home' 
									  when (MSTA.RequestTypeID = 10 and PPA.PresentStatus NOT IN ('Work From Home')) THEN 
									                                                             case when ((CAST(PPA.AdjustOuttime AS TIME)) < (CAST(TSH.ShiftEndTime AS TIME))) then 'Half Day' else 'Present' end
									 when MSTA.RequestTypeID = 12 then 'Present' else MSTA.RequestType end 
		,PPA.IsApproved=1 
		,PPA.InTime = case when MSTA.RequestTypeID = 10 then PPA.AdjustInTime else InTime end
		,PPA.OutTime= case when MSTA.RequestTypeID = 10 then PPA.AdjustOuttime else OutTime end 
		,StatusAlert = case when MSTA.RequestTypeID = 10 then (CASE WHEN (((-1) * DATEDIFF(MINUTE, TSH.ShiftStartTime,   CONVERT(VARCHAR(8),PPA.AdjustInTime,108))) >= 0) THEN 'Green' ELSE 'Red' END)  else  StatusAlert end
		,LateHours = case when MSTA.RequestTypeID = 10 then (CASE WHEN  ((-1) * DATEDIFF(MINUTE, TSH.ShiftStartTime,   CONVERT(VARCHAR(8),PPA.AdjustInTime,108)) < 0) THEN (DATEDIFF(MINUTE, TSH.ShiftStartTime, CONVERT(VARCHAR(8),PPA.AdjustInTime,108))) ELSE '' END) else LateHours end  
		from MST_TBL_Approvalrequests MSTA
		INNER JOIN  PPMS_TBL_AttendanceMaster PPA  ON MSTA.EmployeeID = PPA.EmployeeID
		INNER JOIN  PPMS_TBL_EmployeeMaster PTE ON PPA.EmployeeID = PTE.Autoid
		left JOIN TBL_Shifts TSH ON TSH.Autoid=PTE.ShiftCatagoryID
		WHERE ApprovedStatus = 'Approved' and MSTA.Autoid = @ApprovalReqID
		and (date BETWEEN PeriodFrom  AND PeriodTo) and MSTA.EmployeeID = @EmployeeIdRequest1   AND  RequestTypeID in (1,2,3,4,5,6,7,8,9,10)

		END
		ELSE
		BEGIN
	    INSERT INTO [PPMS_TBL_AttendanceMaster](EmployeeID, Name, [Date], AttendanceStatus,PresentStatus)
						SELECT AutoID,Name, @LoopDate1,'Waiting for Review',@RequestType
						FROM [PPMS_TBL_EmployeeMaster]  where AutoID = @EmployeeIdRequest1 
						and PPMS_TBL_EmployeeMaster.active=1 
        END

        end
        CLOSE @Enumerator1
		DEALLOCATE @Enumerator1
Posted
Updated 11-May-23 21:27pm
Comments
CHill60 12-May-23 4:21am    
As @Richard-Deeming said "There is almost always a better solution than using a cursor" - in this case I believe you just need to use an inner join to your dates_CTE1 A and PPMS_TBL_AttendanceMaster B ON A.[date] = B.[date] -- you may need to cast the table date to type date if the column is datetime.
Then join that lot to the rest of your query and use set-based updates/inserts.
You might find my article useful - Processing Loops in SQL Server[^]
Member 12926744 16-May-23 5:59am    
Thank you will try that way too .

1 solution

Your syntax is incorrect:
DECLARE CURSOR (Transact-SQL) - SQL Server | Microsoft Learn[^]
SQL
DECLARE Enumerator1 CURSOR FAST_FORWARD FOR
WITH dates_CTE1 (date) As (
    SELECT @Firstday1
    UNION ALL
    SELECT DateAdd(day, 1, date)
    FROM dates_CTE1
    WHERE date < @Lastday1
)
SELECT date
FROM dates_CTE1
OPTION (maxrecursion 365);

OPEN Enumerator1;

DECLARE @LoopDate1 date;
WHILE (1 = 1)
BEGIN
    FETCH NEXT FROM Enumerator1 INTO @LoopDate1;
    If @@FETCH_STATUS <> 0 BREAK;
    ...
END;

CLOSE Enumerator1;
DEALLOCATE Enumerator1;
NB: Cursors are not variables. The names do not start with @, and you need to include the select statement as part of the declaration, not by a later assignment.

Also remember that SQL is intended to be a set-based language. There is almost always a better solution than using a cursor.
 
Share this answer
 
Comments
Member 12926744 16-May-23 6:00am    
Thank you so much .

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900