一路向前的算法
最近在操作数据库时遇到这么一种问题,业务是这样的:工作流相对独立,并且其中有多个状态,进而也存在了多
个状态迁移,在这些状态迁移中存在类似电路的“回路”,而且这些“回路”没有任何标记,如果撇开这些“回路”
,工作流中存在某种意义上的开始状态和结束状态;现在我要取出工作流名称和其起止状态的编号,问题出现啦:由
于初期数据库设计不够合理,数据表中只存有工作流的开始状态,而工作流的中间状态又是无序的,即同一工作流中
的状态不是按1、2、3...进行排序的。费劲思写出如下存储过程,主要思想就是"一路向前",也就是说忽视那些“回
路”一直向前。由于当下有工作任务先将代码贴出,待以后分解,忘不幸看到的你见谅!(^_^) :
/*****************获取工作流的起始状态编号*****************/
create procedure UP_GetAllWFStatus
as
begin
declare @temp_firstStatus int,
@temp_lastStatus int,
@temp_count int,
@temp_totalcount int,
@temp_flag int,
@temp_WorkFlowID int
/***********待返回的结果集********/
create table #FinalResultSet(
Source int,
Destination int,
WorkFlowID int
)
/**********临时表--结果集**********/
create table #StatusFlow(
statusID int,
ID int
)
/**********临时表用以存储某Transition开始状态对应的终止状态*******/
create table #tempStatus (
Destination int
)
/**********临时表用以存储工作流下所有Transition起止状态**********/
create table #affectStatus(
Source int,
Destination int
)
declare cur_allWFID cursor for
select WorkFlowID
from WorkFlows
where WorkFlowID <> '1'
open cur_allWFID
fetch cur_allWFID into @temp_WorkFlowID
while (@@fetch_status = 0)
begin
insert into #FinalResultSet
values('','',@temp_WorkFlowID)
/***********记录满足条件的Transition的起止状态*********/
insert into #affectStatus
select Source, Destination
from Transitions
where WorkFlowID = @temp_WorkFlowID
/*************获取工作流的初始状态*****************/
select @temp_firstStatus = Destination
from Transitions
where TransitionID = (
select initialTransitionID
from WorkFlows
where WorkFlowID = @temp_WorkFlowID)
--set @temp_firstStatus = 9 --参数
set @temp_totalcount = 1
set @temp_flag = 1
/************插入起始状态**********/
insert into #StatusFlow
values(@temp_firstStatus, @temp_totalcount )
/************获取结果*****************/
while( @temp_flag = 1)
begin
set @temp_totalcount = @temp_totalcount + 1
/**********获取起始状态对应的终止状态列表*********/
insert into #tempStatus
select Destination
from #affectStatus
where Source = @temp_firstStatus
/***********遍历#tempStatus筛选出首个未记录在结果集中的状态,并设置为终止状态*********/
declare cur_tempStatus cursor for
select Destination
from #tempStatus
open cur_tempStatus
fetch cur_tempStatus into @temp_lastStatus
while (@@fetch_status = 0)
begin
select @temp_count = count(*)
from #StatusFlow
where statusID = @temp_lastStatus
/********如果结果集中不存在此状态则插入结果集,并把设置其为终止状态********/
if @temp_count = 0
begin
insert into #StatusFlow
values(@temp_lastStatus, @temp_totalcount)
delete from #tempStatus
set @temp_firstStatus = @temp_lastStatus
break
end
fetch cur_tempStatus into @temp_lastStatus
end
/***********如果@@fetch_status不为零说明遍历过程中发现未在结果集中记录的状态*************/
if (@@fetch_status <> 0)
begin
set @temp_flag = 0
end
close cur_tempStatus
deallocate cur_tempStatus
end
update #FinalResultSet
set Source = (select StatusID from #StatusFlow
where ID = (
select min(ID)
from #StatusFlow
)),
Destination = (select StatusID from #StatusFlow
where ID = (
select max(ID)
from #StatusFlow
))
where WorkFlowID = @temp_WorkFlowID
delete from #StatusFlow
delete from #affectStatus
delete from #tempStatus
fetch cur_allWFID into @temp_WorkFlowID
end
close cur_allWFID
deallocate cur_allWFID
select * from #FinalResultSet
drop table #StatusFlow
drop table #affectStatus
drop table #tempStatus
drop table #FinalResultSet
end