I have a stored procedure that goes through a date range, and for each date, looks for a bookable object that is not booked at that date. I am struggling to find a way to convert from this functioning stored procedure that uses while-loop and a temporary table into using something more efficient:
declare @from datetime
declare @to datetime
declare @currentdate datetime
declare @hotelid int
set @from = '2018-06-14 17:00'
set @to = '2019-06-25 14:00'
set @currentdate = DATEADD(dd, DATEDIFF(dd, 0, @from), 0)
set @hotelid = 2
Create table dbo.#AvailableObjectsDateRange
(
Date datetime not null,
Name nvarchar(max) not null,
ObjectId bigint not null,
ProductId bigint not null,
ParentProductId bigint null
)
WHILE (@currentdate < DATEADD(dd, DATEDIFF(dd, 0, @to), 0))
BEGIN
;with Reserved as (select bookableobjectid from hotell.BookingRows as br
join hotell.bookings as b on br.bookingid = b.Id
where b.HotelId = @hotelid and br.bookedto > DateAdd(dd, 1, @currentdate) and
br.bookedfrom < DateAdd(dd, 1, @currentdate) and br.checkedout = 0
and (br.isactive = 1 and b.IsActive = 1))
insert into #AvailableObjectsDateRange select @currentdate, bo.Name, bo.Id,
p.Id, p.ParentId from hotell.BookableObjects as bo
join hotell.products as p on bo.ProductId = p.Id
where bo.hotelid = @hotelid
and UnactivatedAt is null
and p.isaddon = 0
and bo.isactive = 1
and bo.id not in (select * from reserved)
SET @CurrentDate = DATEADD(DAY, 1, @CurrentDate); /*increment current date*/
END
select * from #AvailableObjectsDateRange order by Date
drop table #AvailableObjectsDateRange
It's performance is alright for our cases, but it could probably be much improved still.