当前位置: 首页 > news >正文

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

起因

需求的来源是这样式儿的,我们公司某个部门,原来由副总分管,本月做了组织架构调整,副总和部门经理之间增加了总监,导致不得不大量的修改涉及到的路径,给路径创建一个新版本,增加总监节点,再修各节点的表单。整个调整周期会很长,甚至有调漏掉了的路径。而且还发生了在我发布新版本之前,已经有同事已经发起了流程。

归纳一下其实就是路径的版本切换不及时,有按旧版本发起的流程需要调整成新版本。局限是新版本相比旧版本变化不大,仅是新增了节点。这种问题可以按下面的方法处理。

为了更新这些本该用新版本发起的流程,我写了一个存储过程,输入参数是要更新的requestid,输出参数状态标识@returnFlg、状态文本@returnMsg。

经过

数据结构并不复杂,最大的困难在找节点之间的关系,在泛微其自身的数据结构里是没有记录不同版本的节点之间的关系的。在这存储过程里我先后 了节点的名称和节点的位置作为线索去做判定的,如果两个版本中存在同名的节点,认为是同一个节点。如果根据节点名称没有找到相同节点的话,那就看两个版本中存在不存在位置相近的节点,如果存在,认为是同一个节点。

CREATE procedure workflow_RequestVersion_Update
@requestid int,
@returnFlg nvarchar(1) output,
@returnMsg nvarchar(1000) output

as


-- 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, -- 工作流请求节点操作人信息ID
@tolerancex int, -- 横坐标容差
@tolerancey int -- 纵坐标容差

-- 0.2 设置坐标位置容差,虽然不知道是按节点的什么位置记录的坐标位置,但能肯定的是坐标的单位是像素。
select @tolerancex = 5,
@tolerancey = 5

IF OBJECT_ID('tempdb..#workflow_currentoperator_v') IS NOT NULL
DROP 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.id
from workflow_base -- 工作流基本信息表
where id = @workflowidOld

-- 找每个节点的新的nodeid,给它们都先存到临时表里
insert into #workflow_currentoperator_v
(id, requestid, nodeidold, workflowidold )
select id, requestid, nodeid, workflowid
from workflow_currentoperator
where requestid = @requestid

declare workflowidold_Cursor CURSOR for
SELECT id, nodeidold
FROM #workflow_currentoperator_v

open workflowidold_Cursor
FETCH NEXT FROM workflowidold_Cursor into @currentoperatorid, @nodeidOld

while @@FETCH_STATUS = 0
begin

-- 3、 有了新版本的ID,找对应的节点的ID
-- “是同一个节点”的判断原则:要么名称相同,要么位置相同。

select @nodename = nodename -- 节点名称
from workflow_nodebase
where id = @nodeidOld --当前节点id(现在的)

-- 3.1.1 找“名称相同”的节点

select @nodeidnew = id
from workflow_nodebase
where id in ( select nodeid
from workflow_nodehtmllayout
where workflowid = @workflowidNew) and
nodename = @nodename

-- 3.1.2 如果按名称没有找到对应的节点,
if isnull(@nodeidNew ,0) = 0
begin
-- 这里应该是个存储过程,因为坐标可能存在误差。
-- 坐标是以像素为单位记的。
-- 取当前节点的坐标
select @drawxpos = drawxpos,
@drawypos = drawypos
from workflow_nodebase
where id = @nodeidOld --当前节点id(现在的)

-- 3.1.2 如果没有“名称相同”的节点,再去根据位置找节点。
select @nodeidNew = id
from workflow_nodebase
where id in ( select nodeid
from workflow_nodehtmllayout
where workflowid = @workflowidNew) and
drawxpos between @drawxpos - @tolerancex and @drawxpos + @tolerancex and
drawypos between @drawypos - @tolerancey and @drawypos + @tolerancey
end

-- 3.1.4 根据@currentnodeidnew,判断是报异常并退出,还是更新临时表。
if isnull(@nodeidNew ,0) = 0
begin
-- 没找到的话,报错退出
select @returnFlg = 'E',
@returnMsg = '更新失败!流程ID:' + CAST(@requestid AS NVARCHAR(10)) + ',节点:' + @nodename + ',没找到对应节点。'

-- 退出整个存储过程
CLOSE workflowidold_Cursor
DEALLOCATE workflowidold_Cursor
IF OBJECT_ID('tempdb..#workflow_currentoperator_v') IS NOT NULL
begin
DROP TABLE #workflow_currentoperator_v
end
RETURN

end
else
begin
-- 找到的话,更新临时表
update #workflow_currentoperator_v
set nodeidnew = @nodeidNew,
workflowidnew = @workflowidNew
where id = @currentoperatorid

-- 3.1.5 比对表头里的当前节点ID、操作节点ID,是不是和现在正处理的节点ID相同,如果是,取新ID
if @currentnodeidOld = @nodeidOld
begin
select @currentnodeidNew = @nodeidNew
end

if @lastnodeIdOld = @nodeidOld
begin
select @lastnodeIdNew = @nodeidNew
end

end

FETCH NEXT FROM workflowidold_Cursor into @currentoperatorid, @nodeidOld
end

-- 4. 关闭并释放游标
CLOSE workflowidold_Cursor
DEALLOCATE workflowidold_Cursor

-- 5、更新表头workflow_requestbase,更新wrokflowid、lastnodeid、currentnodeid
begin tran
BEGIN TRY

update workflow_requestbase
set workflowid = @workflowidNew,
lastnodeid = isnull(@lastnodeidNew, lastnodeid),
currentnodeid = isnull(@currentnodeidNew, currentnodeid)
where requestid = @requestid

update a
set a.nodeid = b.nodeidNew,
a.workflowid = b.workflowidNew
from workflow_currentoperator a
inner join
#workflow_currentoperator_v b
on a.id = b.id
where a.requestid = @requestid

select @returnFlg = 'S',
@returnMsg = '更新成功!流程ID:' + CAST(@requestid AS NVARCHAR(10)) + ',更新完毕。'

COMMIT tran;
END TRY
BEGIN CATCH
-- 3. 如果发生任何错误,回滚事务
ROLLBACK TRANSACTION;
-- 可以在此处记录错误信息
select @returnFlg = 'E',
@returnMsg = '更新失败!流程ID:' + CAST(@requestid AS NVARCHAR(10)) + ',更新失败。'

END CATCH;

GO

结果

写到这里基本可以满足我自己的要求,并且测试通过了。不得不承认它有一定的局限性,如果工作流的活动版本比当前流程对应的工作流版本少节点的话,缺少的那个节点就更新不到了。

写到这里呢,这次想分享的知识点就全部分享结束了。用那句老掉牙的话收个尾吧,希望这篇文章对已经看到这儿的小伙伴们有所帮助。还是那句话,喜欢的小伙伴们请关注、点赞、评论。大家的鼓励是我持续创作的动力。感谢!

http://www.jsqmd.com/news/1209089/

相关文章:

  • CentOS 8安装与配置完整指南
  • 2026年7月最新银川防水补漏权威指南:卫生间/屋面/外墙/地下室正规施工+透明报价+避坑全攻略 - 吉林同城获客
  • Linux系统安装配置与开发环境搭建指南
  • 江诗丹顿中国官方专柜客户服务电话权威信息声明(2026年7月最新) - 江诗丹顿官方服务中心
  • 如何轻松解决魔兽争霸3兼容性问题:WarcraftHelper完整使用指南
  • PyTorch实现MNIST手写数字识别:CNN实战教程
  • 无锡宜兴 2026 年 7 月外墙厨房车库防水 宜兴正规漏水检测维修商家 - 苏易修缮
  • 【高录用快见刊,最快刊后1个月内上知网谷歌学术 | 主题不设限,艺术、语言、文化、社会学等人文社科主题均可】第五届公共艺术与人文发展国际学术会议 (ICPAHD 2026)
  • ELF 1开发板电源架构与DC-DC转换设计详解
  • 云智能制造一体化平台【程序源代码】
  • 2026年7月最新济南万国官方售后服务网点地址及客服电话一览 - 万国中国官方服务中心
  • 智慧档案室全生命周期运维真相:为什么“售后体系“才是选型的终极标准
  • 机器学习学习路径与资源全指南
  • 2小时,做了一套扫码出入库流程,仓库效率直接翻倍!
  • 芒果派MQ Quad开发板全解析:硬件配置与GPIO开发实战
  • AI辅助VASP计算:Claude Code与vasp-ase集成实践指南
  • Cloud Run 无服务器部署实战:从容器化到生产环境全流程解析
  • 2026 影视后期人才缺口扩大,零基础转行:梵映、好影两大线上机构全面测评 - 资讯报道
  • 使用js-audio-recorder实现Web录音功能全解析
  • C#中的内部类与分部类
  • Falco与Venafi集成:构建以证书为中心的云原生主动安全响应
  • Windows安装Linux虚拟机全流程与优化指南
  • 从录音→纪要→待办→飞书/钉钉自动同步:Claude+Zapier零代码集成全链路(实测延迟<8.3秒,附拓扑图)
  • 开发者紧急预警:Gemini v2.5实时翻译SDK存在会话状态泄漏漏洞(附Google官方未披露的临时修复补丁)
  • 2026 年全能型在线 AI 图片编辑汇总榜单,修图设计生图一体,Imagegood 登顶工具优选席位 - GrowUME
  • YOLOv10目标检测架构解析与部署实践
  • Arm Ethos-U65 介绍(1) 架构、数据格式与算子
  • 2026年7月最新宝鸡防水补漏权威指南:卫生间/屋面/外墙/地下室正规施工+透明报价+避坑全攻略 - 吉林同城获客
  • 积家中国官方售后服务中心|服务热线及全部官方地址权威信息公示(2026年7月更新) - 积家官方售后服务中心
  • 14代酷睿10cm嵌入式单板介绍(100×100mm NANO-ITX工业主板支持DDR5)