Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
tribune
Posting Yak Master
105 Posts |
Posted - 2004-04-26 : 20:46:26
|
| I need to create a line-item invoice for a reservation of a property. SQL server needs to insert a record into a line-item table for each date in the reservation. For example, the finished product for the calculation of a reservation for April 28th - May 5th looks like so:BookingOrderChargeID BookingOrderID ChargeName ChargeType TotalAmount LineItemNum -------------------- -------------- -------------------- ---------- ----------- ----------- 79 159 Reservation April 28 N 120.00 180 159 Reservation April 29 N 120.00 281 159 Reservation April 30 N 135.00 382 159 Reservation May 1st N 135.00 483 159 Reservation May 2nd N 120.00 584 159 Reservation May 3rd N 120.00 685 159 Reservation May 4th N 120.00 786 159 Reservation May 5th N 120.00 8My date range is defined as:declare @BeginningStay datetimedeclare @EndingStay datetimeAnd I have two tables (Rates and RatesCustom) with pricing data. Rates contains default prices, and RatesCustom contains custom prices for special dates such as holidays. If custom rates are found, they override the default rates. Each date of the interval is line-item entered into another table (Charges).Table Layout=============================================================Rates------RateID (int) (pk)UnitID (int) (ID for a property that we're calculating for)DefaultMondayAmount (money)DefaultTuesdayAmount (money)....DefaultSundayAmount (money)RatesCustom-----------RateCustomID (int) (pk)UnitID (int) (ID for a property that we're calculating for)CustomDate (datetime)Amount (money) (this value overrides the default above if record exists)There is also clustered index on RatesCustom on the fields UnitID, CustomDate, I hope this is right :)Charges-------ChargeID (int) (pk)OrderID (int)ChargeName (varchar) (format: "Reservation Month[rd][st][th][nd]")AmountLineItemNum[/quote]Current Stored Procedure==================================================================create proc OnlineBookingChargesGenerate2( @BookingOrderID int)asbeginset nocount ondeclare @UnitID int -- Unit for booking orderdeclare @LineItemNum tinyint -- This is our line item number, which is incremented for each charge inserted into OnlineBookingOrderChargesdeclare @BeginningStay datetime -- Beginning day of reservationdeclare @EndingStay datetime -- Ending day of reservationdeclare @BookingOrderChargeID int -- ID of inserted charge, comes from OnlineBookingOrderChargeInsert return value-- Check for valid Booking Orderif not exists(select BookingOrderID from OnlineBookingOrders where BookingOrderID = @BookingOrderID) return -1-- Check to make sure Booking Order's charges have not already been generated (modifications to order may not be done through this procedure)if exists(select BookingOrderID from OnlineBookingOrderCharges where BookingOrderID = @BookingOrderID) return -1-- Assign local variablesselect @BeginningStay = BeginningStay, @EndingStay = EndingStay, @UnitID = UnitID from OnlineBookingOrders where BookingOrderID = @BookingOrderID-- Calculate rent charges from reservationdeclare @CurrentDate datetimedeclare @Quantity tinyintdeclare @UnitPrice moneydeclare @Amount moneyset @Quantity = 1set @CurrentDate = @BeginningStayset @LineItemNum = 1while @CurrentDate <= @EndingStaybegin if exists(select * from RatesCustom where UnitID = @UnitID and CustomDate = @CurrentDate) begin -- insert line-item charge insert into OnlineBookingOrderCharges ( BookingOrderID, ChargeName, ChargeType, ChargeStatus, UnitPrice, Quantity, TotalAmount, LineItemNum ) select @BookingOrderID, 'Reservation ' + datename(m, @CurrentDate) + ' ' + datename(d, @CurrentDate) + case when datename(d, @CurrentDate) IN ('1', '21', '31') then 'st' when datename(d, @CurrentDate) IN ('2', '22') then 'nd' when datename(d, @CurrentDate) IN ('3', '23') then 'rd' ELSE 'th' end, 'N', 'A', Amount, @Quantity, Amount * @Quantity, @LineItemNum from RatesCustom where UnitID = @UnitID and CustomDate = @CurrentDate -- increment line-item # set @LineItemNum = @LineItemNum + 1 -- increment current date set @CurrentDate = DateAdd(d, 1, @CurrentDate) end else begin -- find our prices from Rates table select @Amount = case datename(weekday, @CurrentDate) when 'Monday' then DefaultMondayAmount when 'Tuesday' then DefaultTuesdayAmount when 'Wednesday' then DefaultWednesdayAmount when 'Thursday' then DefaultThursdayAmount when 'Friday' then DefaultFridayAmount when 'Saturday' then DefaultSaturdayAmount when 'Sunday' then DefaultSundayAmount end from Rates where UnitID = @UnitID print cast(@Amount as varchar(100)) -- insert line-item charge insert into OnlineBookingOrderCharges ( BookingOrderID, ChargeName, ChargeType, ChargeStatus, UnitPrice, Quantity, TotalAmount, LineItemNum ) select @BookingOrderID, 'Reservation ' + datename(m, @CurrentDate) + ' ' + datename(d, @CurrentDate) + case when datename(d, @CurrentDate) IN ('1', '21', '31') then 'st' when datename(d, @CurrentDate) IN ('2', '22') then 'nd' when datename(d, @CurrentDate) IN ('3', '23') then 'rd' ELSE 'th' end, 'N', 'A', @Amount, @Quantity, @Amount * @Quantity, @LineItemNum -- increment line-item # set @LineItemNum = @LineItemNum + 1 -- increment current date set @CurrentDate = DateAdd(d, 1, @CurrentDate) endendend=====================================================================End stored procedure=====================================================================My question is how can I avoid the while statement in the stored procedure, or speed up the query in any way. The custom rates table could eventually have 200,000 records, and with a reservation spanning three weeks, thats 4,200,000 queries.Would it help to redesign the pricing tables?Much appreciated,-trib |
|
|
tribune
Posting Yak Master
105 Posts |
Posted - 2004-04-26 : 20:47:59
|
Alright I'll try this code paste again...create proc OnlineBookingChargesGenerate2( @BookingOrderID int)asbeginset nocount ondeclare @UnitID int -- Unit for booking orderdeclare @LineItemNum tinyint -- This is our line item number, which is incremented for each charge inserted into OnlineBookingOrderChargesdeclare @BeginningStay datetime -- Beginning day of reservationdeclare @EndingStay datetime -- Ending day of reservationdeclare @BookingOrderChargeID int -- ID of inserted charge, comes from OnlineBookingOrderChargeInsert return value-- Check for valid Booking Orderif not exists(select BookingOrderID from OnlineBookingOrders where BookingOrderID = @BookingOrderID) return -1-- Check to make sure Booking Order's charges have not already been generated (modifications to order may not be done through this procedure)if exists(select BookingOrderID from OnlineBookingOrderCharges where BookingOrderID = @BookingOrderID) return -1-- Assign local variablesselect @BeginningStay = BeginningStay, @EndingStay = EndingStay, @UnitID = UnitID from OnlineBookingOrders where BookingOrderID = @BookingOrderID-- Calculate rent charges from reservationdeclare @CurrentDate datetimedeclare @Quantity tinyintdeclare @UnitPrice moneydeclare @Amount moneyset @Quantity = 1set @CurrentDate = @BeginningStayset @LineItemNum = 1while @CurrentDate <= @EndingStaybegin if exists(select * from RatesCustom where UnitID = @UnitID and CustomDate = @CurrentDate) begin -- insert line-item charge insert into OnlineBookingOrderCharges ( BookingOrderID, ChargeName, ChargeType, ChargeStatus, UnitPrice, Quantity, TotalAmount, LineItemNum ) select @BookingOrderID, 'Reservation ' + datename(m, @CurrentDate) + ' ' + datename(d, @CurrentDate) + case when datename(d, @CurrentDate) IN ('1', '21', '31') then 'st' when datename(d, @CurrentDate) IN ('2', '22') then 'nd' when datename(d, @CurrentDate) IN ('3', '23') then 'rd' ELSE 'th' end, 'N', 'A', Amount, @Quantity, Amount * @Quantity, @LineItemNum from RatesCustom where UnitID = @UnitID and CustomDate = @CurrentDate -- increment line-item # set @LineItemNum = @LineItemNum + 1 -- increment current date set @CurrentDate = DateAdd(d, 1, @CurrentDate) end else begin -- find our prices from Rates table select @Amount = case datename(weekday, @CurrentDate) when 'Monday' then DefaultMondayAmount when 'Tuesday' then DefaultTuesdayAmount when 'Wednesday' then DefaultWednesdayAmount when 'Thursday' then DefaultThursdayAmount when 'Friday' then DefaultFridayAmount when 'Saturday' then DefaultSaturdayAmount when 'Sunday' then DefaultSundayAmount end from Rates where UnitID = @UnitID print cast(@Amount as varchar(100)) -- insert line-item charge insert into OnlineBookingOrderCharges ( BookingOrderID, ChargeName, ChargeType, ChargeStatus, UnitPrice, Quantity, TotalAmount, LineItemNum ) select @BookingOrderID, 'Reservation ' + datename(m, @CurrentDate) + ' ' + datename(d, @CurrentDate) + case when datename(d, @CurrentDate) IN ('1', '21', '31') then 'st' when datename(d, @CurrentDate) IN ('2', '22') then 'nd' when datename(d, @CurrentDate) IN ('3', '23') then 'rd' ELSE 'th' end, 'N', 'A', @Amount, @Quantity, @Amount * @Quantity, @LineItemNum -- increment line-item # set @LineItemNum = @LineItemNum + 1 -- increment current date set @CurrentDate = DateAdd(d, 1, @CurrentDate) endendend |
 |
|
|
tribune
Posting Yak Master
105 Posts |
Posted - 2004-04-28 : 12:24:18
|
| anyone? |
 |
|
|
|
|
|
|
|