以下是我的存储过程。它包含一个子查询
Select StartTime From DrTimings Where DrID = @DrID
如果此子查询返回多个值,则会出错。子查询返回多行。我想在游标中获取每个@StartTime和@EndTime。意思是我想“从Doctor获取下一个@StTime和@EndTime”
我可以在游标中使用两个参数吗?
ALTER PROCEDURE [dbo].SP_AFK_GetSlotsByDate
@DrID int,
@AppointmentDate Datetime
AS
BEGIN
Declare @StartTime Datetime
Declare @EndTime Datetime
BEGIN
SET @StartTime = (Select StartTime From DrTimings Where DrID = @DrID)
SET @EndTime = (Select EndTime From DrTimings Where DrID = @DrID)
END
DECLARE Doctor CURSOR FOR
Select StartTime from TimeList1 where StartTime>=@StartTime and StartTime<@EndTime
Declare @StTime datetime
Declare @SlotID int
Declare @AppointmentTime datetime
Declare @TempSlots Table (SlotID int , AppointmentTime datetime null)
Insert into
@TempSlots
(
SlotID ,
AppointmentTime
)
values(
0,
Getdate()
)
open Doctor
fetch next from Doctor into @StTime
while @@fetch_status = 0
Begin
Select @SlotID= T.SlotId from TimeList1 T
where T.StartTime>=@StartTime and T.StartTime<@EndTime and
T.SlotId not in
(Select A.SlotId from AppointmentSheet A where A.AppointmentDate=@AppointmentDate)
Select @AppointmentTime = Convert(varchar,right(T.StartTime,7),131)+' - '+ Convert(varchar,right(T.EndTime,7),131)
from TimeList1 T
where T.StartTime>=@StartTime and T.StartTime<@EndTime and
T.SlotId not in
(Select A.SlotId from AppointmentSheet A where A.AppointmentDate=@AppointmentDate)
Update @TempSlots
Set SlotID = @SlotID,
AppointmentTime=@AppointmentTime
fetch next from Doctor into @StTime
end
close Doctor
deallocate Doctor
Select * From @TempSlots
END
答案 0 :(得分:1)
只需以这种方式添加下一个变量:
fetch next from Doctor into @StTime, @EndTime
光标的select语句应包含EndTime:
列select StartTime, EndTime
from TimeList1
where StartTime>=@StartTime and StartTime<@EndTime
答案 1 :(得分:1)
虽然游标是迭代结果集的简单方法,但由于性能影响,它们不推荐。
如果我知道 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的最新值,则甚至不需要迭代。