E8-写了一个存储过程,用来更新流程的对应版本

📅 2026/7/17 21:23:48 ✍️ 编辑团队 👁️ 阅读次数
E8-写了一个存储过程,用来更新流程的对应版本
起因需求的来源是这样式儿的我们公司某个部门原来由副总分管本月做了组织架构调整副总和部门经理之间增加了总监导致不得不大量的修改涉及到的路径给路径创建一个新版本增加总监节点再修各节点的表单。整个调整周期会很长甚至有调漏掉了的路径。而且还发生了在我发布新版本之前已经有同事已经发起了流程。归纳一下其实就是路径的版本切换不及时有按旧版本发起的流程需要调整成新版本。局限是新版本相比旧版本变化不大仅是新增了节点。这种问题可以按下面的方法处理。为了更新这些本该用新版本发起的流程我写了一个存储过程输入参数是要更新的requestid输出参数状态标识returnFlg、状态文本returnMsg。经过数据结构并不复杂最大的困难在找节点之间的关系在泛微其自身的数据结构里是没有记录不同版本的节点之间的关系的。在这存储过程里我先后 了节点的名称和节点的位置作为线索去做判定的如果两个版本中存在同名的节点认为是同一个节点。如果根据节点名称没有找到相同节点的话那就看两个版本中存在不存在位置相近的节点如果存在认为是同一个节点。CREATE procedure workflow_RequestVersion_Updaterequestid int,returnFlg nvarchar(1) output,returnMsg nvarchar(1000) outputas-- 0.1 定义需要用取的变量declare workflowidOld int, -- 工作流id(当前的)workflowidNew int, -- 工作流id(新的)workflowname varchar(1000), -- 工作流名称currentnodeidOld int, -- 当前节点id当前的currentnodeidNew int, -- 当前节点id新的lastnodeidOld int, --lastnodeidNew int,nodeidOld int, -- 节点id当前的nodeidNew int, -- 节点id新的nodename varchar(1000), -- 当前节点名称现在的drawxpos int, -- 节点图形显示横坐标drawypos int, -- 节点图形显示纵坐标currentoperatorid int, -- 工作流请求节点操作人信息IDtolerancex int, -- 横坐标容差tolerancey int -- 纵坐标容差-- 0.2 设置坐标位置容差虽然不知道是按节点的什么位置记录的坐标位置但能肯定的是坐标的单位是像素。select tolerancex 5,tolerancey 5IF OBJECT_ID(tempdb..#workflow_currentoperator_v) IS NOT NULLDROP TABLE #workflow_currentoperator_v;-- 0,3 创建临时表存储当前流程实例的节点信息create table #workflow_currentoperator_v (id int,requestid int,nodeidold int,nodeidnew int,workflowidold int,workflowidnew int)-- 1、 用传入的参数requestid找到对应的workflowid等表头里的信息。select workflowidOld workflowid, -- 工作流id当前的currentnodeidOld currentnodeid, -- 当前节点id当前的lastnodeidOld lastnodeid -- 最后操作节点id当前的from workflow_requestbase -- 工作流请求基本信息表where requestid requestid-- 2、 用获得的workflowid找对应的workflowname和activeVersionID-- 测试过发现一旦修改了路径名称所有版本会同时修改具备用workflowname作为主键的条件。select workflowname workflowname, -- 工作流名称workflowidNew activeVersionID -- 当前流程所属活动版本ID 这里记录的是活动的那个版本的workflowbase.idfrom workflow_base -- 工作流基本信息表where id workflowidOld-- 找每个节点的新的nodeid给它们都先存到临时表里insert into #workflow_currentoperator_v(id, requestid, nodeidold, workflowidold )select id, requestid, nodeid, workflowidfrom workflow_currentoperatorwhere requestid requestiddeclare workflowidold_Cursor CURSOR forSELECT id, nodeidoldFROM #workflow_currentoperator_vopen workflowidold_CursorFETCH NEXT FROM workflowidold_Cursor into currentoperatorid, nodeidOldwhile FETCH_STATUS 0begin-- 3、 有了新版本的ID找对应的节点的ID-- “是同一个节点”的判断原则要么名称相同要么位置相同。select nodename nodename -- 节点名称from workflow_nodebasewhere id nodeidOld --当前节点id现在的-- 3.1.1 找“名称相同”的节点select nodeidnew idfrom workflow_nodebasewhere id in ( select nodeidfrom workflow_nodehtmllayoutwhere workflowid workflowidNew) andnodename nodename-- 3.1.2 如果按名称没有找到对应的节点if isnull(nodeidNew ,0) 0begin-- 这里应该是个存储过程因为坐标可能存在误差。-- 坐标是以像素为单位记的。-- 取当前节点的坐标select drawxpos drawxpos,drawypos drawyposfrom workflow_nodebasewhere id nodeidOld --当前节点id现在的-- 3.1.2 如果没有“名称相同”的节点再去根据位置找节点。select nodeidNew idfrom workflow_nodebasewhere id in ( select nodeidfrom workflow_nodehtmllayoutwhere workflowid workflowidNew) anddrawxpos between drawxpos - tolerancex and drawxpos tolerancex anddrawypos between drawypos - tolerancey and drawypos toleranceyend-- 3.1.4 根据currentnodeidnew判断是报异常并退出还是更新临时表。if isnull(nodeidNew ,0) 0begin-- 没找到的话报错退出select returnFlg E,returnMsg 更新失败流程ID CAST(requestid AS NVARCHAR(10)) 节点 nodename 没找到对应节点。-- 退出整个存储过程CLOSE workflowidold_CursorDEALLOCATE workflowidold_CursorIF OBJECT_ID(tempdb..#workflow_currentoperator_v) IS NOT NULLbeginDROP TABLE #workflow_currentoperator_vendRETURNendelsebegin-- 找到的话更新临时表update #workflow_currentoperator_vset nodeidnew nodeidNew,workflowidnew workflowidNewwhere id currentoperatorid-- 3.1.5 比对表头里的当前节点ID、操作节点ID是不是和现在正处理的节点ID相同如果是取新IDif currentnodeidOld nodeidOldbeginselect currentnodeidNew nodeidNewendif lastnodeIdOld nodeidOldbeginselect lastnodeIdNew nodeidNewendendFETCH NEXT FROM workflowidold_Cursor into currentoperatorid, nodeidOldend-- 4. 关闭并释放游标CLOSE workflowidold_CursorDEALLOCATE workflowidold_Cursor-- 5、更新表头workflow_requestbase更新wrokflowid、lastnodeid、currentnodeidbegin tranBEGIN TRYupdate workflow_requestbaseset workflowid workflowidNew,lastnodeid isnull(lastnodeidNew, lastnodeid),currentnodeid isnull(currentnodeidNew, currentnodeid)where requestid requestidupdate aset a.nodeid b.nodeidNew,a.workflowid b.workflowidNewfrom workflow_currentoperator ainner join#workflow_currentoperator_v bon a.id b.idwhere a.requestid requestidselect returnFlg S,returnMsg 更新成功流程ID CAST(requestid AS NVARCHAR(10)) 更新完毕。COMMIT tran;END TRYBEGIN CATCH-- 3. 如果发生任何错误回滚事务ROLLBACK TRANSACTION;-- 可以在此处记录错误信息select returnFlg E,returnMsg 更新失败流程ID CAST(requestid AS NVARCHAR(10)) 更新失败。END CATCH;GO结果写到这里基本可以满足我自己的要求并且测试通过了。不得不承认它有一定的局限性如果工作流的活动版本比当前流程对应的工作流版本少节点的话缺少的那个节点就更新不到了。写到这里呢这次想分享的知识点就全部分享结束了。用那句老掉牙的话收个尾吧希望这篇文章对已经看到这儿的小伙伴们有所帮助。还是那句话喜欢的小伙伴们请关注、点赞、评论。大家的鼓励是我持续创作的动力。感谢