一路向前的算法

  最近在操作数据库时遇到这么一种问题,业务是这样的:工作流相对独立,并且其中有多个状态,进而也存在了多
个状态迁移,在
这些状态迁移中存在类似电路的“回路”,而且这些“回路”没有任何标记,如果撇开这些“回路”
,工作流中存在某种意义上的开始状态和结束状态;
现在我要取出工作流名称和其起止状态的编号,问题出现啦:由
于初期数据库设计不够合理,数据表中只存有工作流的开始状态,而工作流的中间状态又是无序的,即同一工作流中
的状态不是按
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

原文地址:https://www.cnblogs.com/xtzhilv/p/xitianzhilv_1.html