news 2026/7/17 21:23:33

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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

结果

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 21:23:22

Arm Ethos-U65 介绍(1) 架构、数据格式与算子

概述 产品定位 Arm Ethos-U 系列是 Arm 为微处理器系统实现边缘计算设计的 NPU IP 核,旨在以极低的功耗和芯片面积高效加速机器学习推理任务,推荐和Cortex-M处理器搭配,当前包括U55、U65、U85三款产品。 本文以U65进行介绍,U65 支…

作者头像 李华
网站建设 2026/7/17 21:18:37

【ChatGPT儿童故事创作黄金法则】:20年教育科技专家亲授——3步生成高互动、零说教、符合发展心理学的AI故事

更多请点击: https://intelliparadigm.com 第一章:ChatGPT儿童故事创作的底层逻辑与教育伦理边界 ChatGPT在儿童故事生成中并非简单地拼接词汇,而是基于大规模语料中习得的叙事模式、角色关系图谱与情感韵律结构进行概率化重构。其底层逻辑依…

作者头像 李华
网站建设 2026/7/17 21:17:54

5分钟学会HashCalculator:免费文件完整性校验终极指南

5分钟学会HashCalculator:免费文件完整性校验终极指南 【免费下载链接】HashCalculator 哈希值计算工具,批量计算/批量校验/查找重复文件/改变哈希值等,支持集成到系统右键菜单 项目地址: https://gitcode.com/gh_mirrors/ha/HashCalculato…

作者头像 李华
网站建设 2026/7/17 21:16:46

CW32开发板与DFPlayer Mini的MP3播放系统实现

1. CW32饭盒派开发板与MP3模块概述CW32饭盒派是一款基于国产CW32微控制器的开源开发板,因其小巧的尺寸和丰富的接口资源被开发者亲切地称为"饭盒派"。这款开发板特别适合物联网和嵌入式音频应用的快速原型开发,其核心优势在于:采用…

作者头像 李华
网站建设 2026/7/17 21:11:45

Ubuntu软件管理全指南:从APT到Snap安装与卸载

1. Ubuntu软件管理基础认知作为一个长期使用Ubuntu的开发者,我深刻体会到掌握软件安装与卸载技巧对提升工作效率的重要性。与Windows系统不同,Ubuntu采用独特的包管理机制,这套系统既强大又精密,需要我们从底层理解其运作原理。Ub…

作者头像 李华