Хотя курсоры - это простой способ перебора набора результатов, они не рекомендуются из-за влияния на производительность.
Если бы я знал структуру вашей таблицы TimeList1 и ее связь с таблицей DrTimings, я бы порекомендовал версию, в которой не использует курсоры.
Однако после просмотра вашего T-SQL я решил предоставить вам обновленную версию, которая уменьшает избыточность и использует JOINS вместо подзапросов:
ALTER PROCEDURE [dbo].SP_AFK_GetSlotsByDate
(
@DrID int,
@AppointmentDate DateTime
)
AS
DECLARE
@StartTime DateTime,
@EndTime DateTime,
@SlotID int,
@AppointmentTime DateTime;
-- Retrieve the initial values for StartTime and EndTime
-- These values get overwritten by the cursor (?)
SELECT
@StartTime = StartTime,
@EndTime = EndTime
FROM
DrTimings
WHERE
DrID = @DrID;
DECLARE @TempSlots TABLE
(
SlotID int,
AppointmentTime datetime NULL
);
-- Set default values
INSERT @TempSlots (SlotID,AppointmentTime)
VALUES (0, GETDATE());
DECLARE Doctor CURSOR FOR
SELECT
StartTime,
EndTime
FROM
TimeList1
where
StartTime >= @StartTime AND
StartTime < @EndTime;
OPEN Doctor
FETCH NEXT FROM Doctor INTO @StartTime,@EndTime
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
@SlotID = T.SlotId,
@AppointmentTime = CONVERT(varchar,RIGHT(T.StartTime,7),131)
+ ' - ' + CONVERT(varchar,RIGHT(T.EndTime,7),131)
FROM
TimeList1 T
LEFT JOIN AppointmentSheet A ON T.SlotId = A.SlotId
WHERE
T.StartTime >= @StartTime AND
T.StartTime < @EndTime AND
A.AppointmentDate = @AppointmentDate AND
A.SlotId IS NULL;
-- This table will always be updated to contain the latest values
-- it will contain only one row
UPDATE
@TempSlots
SET
SlotID = @SlotID,
AppointmentTime = @AppointmentTime;
FETCH NEXT FROM Doctor INTO @StartTime,@EndTime
END
CLOSE Doctor
DEALLOCATE Doctor
-- Return results
SELECT
SlotId,
AppointmentTime
FROM
@TempSlots;
Обновление : Если целью является получение последних значений для SlotId и AppointmentTime, то итерация даже не требуется.