我需要在SQL Server 2008中创建一个存储过程,它将根据某个值更新表。这里的技巧是我需要递归搜索表,直到找到我要查找的值,然后更新当前记录。例如,我有一个包含3列的Employees表:
EMPLOYEEID
经理ID
FAMILYID
对于表中的每个EmployeeId,我想获得它的ManagerId。然后,如果ManagerID!= 0,则转到并获取当前ManagerId的ManagerId(每个ManagerId将指向一个EmployeeId) - 继续执行此操作直到我到达顶级管理器(其中ManagerId == 0)。
找到顶级经理后,我想更新原始记录中的FamilyId列,该记录以上述流程的最后一个EmployeeId的值启动流程。
基本上我需要对表中的每条记录执行此操作。我正在尝试将FamilyId设置为层次结构中所有员工和经理的根管理器的值。
我不确定是否应该使用游标或CTE来完成此操作 - 或者只是在代码中执行此操作。
非常感谢任何帮助。
谢谢!
答案 0 :(得分:5)
您也可以使用递归CTE。
;WITH Hierarchy
As (SELECT EmployeeId AS _EmployeeId,
ManagerId AS _ManagerId,
EmployeeId AS _FamilyId
FROM @Employee
WHERE ManagerId = 0
UNION ALL
SELECT e.EmployeeId,
e.ManagerId,
h._FamilyId
FROM @Employee e
JOIN Hierarchy h
ON h._EmployeeId = e.ManagerId)
UPDATE @Employee
SET FamilyId = _FamilyId
FROM Hierarchy h
WHERE EmployeeId = _EmployeeId
答案 1 :(得分:2)
这是我第一次尝试它。我希望我明白你的要求。
declare @Employee table (
EmployeeId int not null
, ManagerId int not null
, FamilyId int null
)
-- 1 6
-- / \ / \
-- 2 3 7 8
-- / \
-- 4 5
insert @Employee values (1, 0, null)
insert @Employee values (2, 1, null)
insert @Employee values (3, 1, null)
insert @Employee values (4, 2, null)
insert @Employee values (5, 2, null)
insert @Employee values (6, 0, null)
insert @Employee values (7, 6, null)
insert @Employee values (8, 6, null)
-- the data before the update
select * from @Employee
-- initial update to get immediate managers
update Employee
set FamilyId = Manager.EmployeeId
from @Employee Employee
inner join @Employee Manager on Manager.EmployeeId = Employee.ManagerId
-- the data after the first update
select * from @Employee
-- do more updates until done
while exists (
select *
from @Employee
where (
FamilyId is not null
and FamilyId not in (
select EmployeeId from @Employee where ManagerId = 0
)
)
)
begin
update Employee
set FamilyId = Manager.ManagerId
from @Employee Employee
inner join @Employee Manager on Manager.EmployeeId = Employee.FamilyId
where (
Employee.FamilyId is not null
and Employee.FamilyId not in (
select EmployeeId from @Employee where ManagerId = 0
)
)
end
-- the data after all updates
select * from @Employee
我确信有更聪明的方法
答案 2 :(得分:0)
我怀疑我会为此调用用户定义的函数(UDF)。 UDF将以递归方式调用自身。
尝试使用google搜索:递归UDF sql server
这个链接似乎给出了一个例子(虽然他们确实注意到从SQL 2000开始,你只能递归32级深度。) http://weblogs.sqlteam.com/jeffs/archive/2003/11/21/588.aspx
很抱歉,我现在没有时间专心致志。如果明天仍然是个问题,我会花更多的时间来解释。