我的存储过程遇到了问题。它应该从给定的位置添加所有孩子,子孙等的值并返回它。目前它返回的只有NULL
。
这是将使用存储过程的表的示例。
稍后我想将操作符Bool实现到存储过程中。如果是NULL
,则在计算中忽略saldo。如果它是0,则saldo被否定地使用,如果它是1,则saldo被正面使用。
id pos operpos saldo operator
-------------------------------------------------
1 blue NULL NULL NULL
2 lightblue blue NULL 1
3 darkblue blue 25.00 1
4 skyblue lightblue 12.00 1
5 babyblue lightblue -12.00 0
6 greyblue lightblue 22.00 1
7 royalblue darkblue 121.00 1
8 navyblue darkblue 20.00 1
9 sailorsblue navyblue 23.00 0
10 captainsblue navyblue 33.00 1
这是calctotal(darkblue)
的存储过程应该计算的内容:
darkblue +25
royalblue +121
navyblue +20
sailorsblue -23 //because operator = 0
captainsblue +33
OUTPUT 176
这是我目前的存储过程:
ALTER PROCEDURE [dbo].[calctotal]
//DECLARE INPUT AND OUTPUT
@number nvarchar(255),
@total NUMERIC(20,2) OUTPUT
AS
BEGIN
//DECLARE THE VARIABLES
DECLARE @pos NVARCHAR(255) = NULL;
DECLARE @saldo NUMERIC(20,2) = NULL;
DECLARE @tmptotal NUMERIC(20,2)
DECLARE @tmptotal2 NUMERIC(20,2) = 0;
//LOAD DATA INTO CURSOR
DECLARE cur CURSOR LOCAL for
SELECT pos, saldo
FROM test
WHERE operpos = @number
//START CURSOR AND FETCH NEXT
OPEN CUR
FETCH NEXT FROM CUR INTO @pos, @tmptotal2
//WHEN NEW ITEM HAS BEEN LOADED
WHILE @@FETCH_STATUS = 0
BEGIN
//ADD VALUE TO TMPTOTAL
SET @tmptotal = @tmptotal2 + @tmptotal;
//RECURSIVE PART SO FUNCTION APPLIES TO CHILDREN
EXEC calctotal @pos, @tmptotal;
END;
close cur
deallocate cur
//THE OUTPUT OF TOTAL IS SET TO THE VALUE OF THE VARIABLE
SET @total = @tmptotal;
END
你们有没有和想法代码可能出错和/或如何纠正它?有关如何实现Operator Boolean的任何提示,我将非常高兴!
提前感谢您的帮助
编辑:我正在使用SQL Server 2012
答案 0 :(得分:1)
试试这个:
;with cte as
(select pos, operpos, saldo, [operator], 0 as level
from tbl
where pos = 'darkblue'
union all
select t.pos,t.operpos, t.saldo, t.[operator], c.level + 1
from tbl t
inner join cte c on c.pos = t.operpos
)
select sum (
case
when [operator] = 0 then (-1 * saldo)
when [operator] = 1 then saldo
else 0
end) as totalsum from cte
这是一个递归的公用表表达式(CTE),可从SQL Server 2005开始提供。我们基本上检索了所有孩子的根值' darkblue'然后根据operator
字段进行条件求和。您可以代替硬编码,而不是传递参数:
...
where pos = @pos
...
请注意,此方法将数据作为一个集处理,并且无需手动处理游标。