【发布时间】:2019-07-30 06:58:09
【问题描述】:
我在我的会计应用程序中使用以下代码计算产品的加权平均值,但是当我的记录增加时,它会引发错误“在语句完成之前已用尽最大递归 100”有什么优化建议吗?
ALTER PROCEDURE [dbo].[ProductBackAveragePrice]
(
@InvoiceFK int,@FromDate char(10),@ToDate char(10),@FinancialFK tinyint
)
AS
SET NOCOUNT ON;
declare @InvoiceID int=0 , @ProductFK int=0
DECLARE q1_cursor CURSOR Dynamic for select InvoiceFK,ProductFK from Sales.InvoiceDetail where FinancialPeriodFK=@FinancialFK and InvoiceFK=@InvoiceFK
open q1_cursor
fetch next from q1_cursor into @InvoiceID,@ProductFK
while @@fetch_status=0
begin
with CTE as (
select RowID,Date,InvoiceID,InvoiceNumber,InvoiceKindFK,[I/O],
OrderQty, UnitPrice=cast(UnitPrice-(isnull(DiscountAmount,0)/nullif(OrderQty,0)) as decimal),
cast( OrderQty as decimal) as QuantityOnHand,
(cast(UnitPrice-(isnull(DiscountAmount,0)/nullif(OrderQty,0)) as decimal)) as AverageUnitCost
from [dbo].[ProductInOutProduct] (@ProductFK,@FromDate,@ToDate,@FinancialFK)
where RowId = 1 -- Starting condition for your single product sample data.
union all
select R.RowID, R.Date,R.InvoiceID,R.InvoiceNumber,R.InvoiceKindFK, R.[I/O],
R.OrderQty, case when (R.InvoiceKindFK=3) then CTE.AverageUnitCost else cast(R.UnitPrice-(isnull(R.DiscountAmount,0)/nullif(R.OrderQty,0)) as decimal) end,
cast(case
when R.[I/O] = 2 then CTE.QuantityOnHand - R.OrderQty -- Sales don't affect the average unit cost.
when R.[I/O] = 1 then CTE.QuantityOnHand + R.OrderQty
else ( CTE.QuantityOnHand) end
as decimal),
-- My accounting is pretty rusty, but this should do some sort of useful averaging.
cast(case
when (R.[I/O] = 2 or R.InvoiceKindFK=3) then cast(CTE.AverageUnitCost as decimal) -- Sales don't affect the average unit cost.
else ( CTE.AverageUnitCost * CTE.QuantityOnHand + (R.UnitPrice-(isnull(R.DiscountAmount,0)/nullif(R.OrderQty,0))) * R.OrderQty ) /
nullif(( CTE.QuantityOnHand + R.OrderQty ),0) end
as decimal)
from CTE inner join
[dbo].[ProductInOutProduct] (@ProductFK,@FromDate,@ToDate,@FinancialFK) as R on R.RowId = CTE.RowID + 1 -- Row by row.
)
UPDATE dt
SET dt.BackPrice = dtu.AverageUnitCost
FROM Sales.InvoiceDetail dt
INNER JOIN CTE dtu ON dt.InvoiceFK = dtu.InvoiceID
WHERE
dt.FinancialPeriodFK = @FinancialFK and dt.InvoiceFK=dtu.InvoiceID and ProductFK=@ProductFK
option (maxrecursion 0);
fetch next from q1_cursor into @InvoiceID,@ProductFK
end
close q1_cursor
deallocate q1_cursor
【问题讨论】:
-
@PeterSmith 因为我只将 InvoiceID 传递给光标,所以它在光标上运行一次
-
你的问题究竟是什么?
-
TSQL Maxrecursion on a cte(和许多其他人)的可能重复
-
@Squirrel 运行此 SP 时由于记录巨大而引发错误,所以请建议我优化代码
-
@EdHarper 没明白你的意思?
标签: sql-server tsql recursion stored-procedures weighted-average