ForeverSmiYngEcologyKit/生成唯一编号(防止高并发重复).sql
wintsa f01e772b06 生成唯一编号(防止高并发重复).sql
生成唯一编号(防止高并发重复),并且有demo,示范如何批量更新历史数据的编号
2025-06-27 16:35:46 +08:00

112 lines
3.9 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

call SP_GENERATE_FORMATTED_SEQUENCE( 'JSXMlxdj' --key同一个模块同一个流程必须唯一 ,
'{?REQUESTID}' --传值 ,
'{?sqrq}' --日期传值,默认传2025-02-11字符串格式,
'formtable_main_1576' --需要被update的表单名称 ,
'jsxmbh' --需要被update的字段名称 ,
'requestid' --被update的where条件的字段名,
'#P-#Y-#S4' --编号排列,#S4代表补位4个比如0014。排列也可以是'[#p-#Y]/#S',输出结果是[JSXM-2025]/1,
'JSXM' --这个就是上面的#p )
--批量更新历史表单的编号
DECLARE
v_count NUMBER := 0;
v_error_count NUMBER := 0;
v_total_count NUMBER := 0;
-- 游标获取所有需要更新的记录按ID排序
CURSOR c_records IS
SELECT xglc, djrq
FROM uf_gcxx
WHERE xglc IS not NULL -- 只更新空编号的记录
ORDER BY xglc; -- 按ID排序
BEGIN
-- 统计总记录数
SELECT COUNT(*) INTO v_total_count
FROM uf_gcxx
WHERE xglc IS not NULL;
DBMS_OUTPUT.PUT_LINE('开始批量更新历史数据...');
DBMS_OUTPUT.PUT_LINE('需要更新的记录总数: ' || v_total_count);
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
-- 遍历每条记录
FOR rec IN c_records LOOP
BEGIN
-- 调用存储过程为每条记录生成编号
SP_GENERATE_FORMATTED_SEQUENCE(
'JSXMlxdj', -- 序列键
rec.xglc, -- 请求ID/记录ID
rec.djrq, -- 日期值
'uf_gcxx', -- 目标表名
'gcbhz', -- 目标字段名
'xglc', -- 记录ID字段名
'#P-#Y-#S4', -- 编号格式模式
'JSXM' -- 前缀
);
v_count := v_count + 1;
-- 每处理100条记录显示一次进度
IF MOD(v_count, 100) = 0 THEN
DBMS_OUTPUT.PUT_LINE('已处理: ' || v_count || '/' || v_total_count || ' 条记录');
END IF;
EXCEPTION
WHEN OTHERS THEN
v_error_count := v_error_count + 1;
DBMS_OUTPUT.PUT_LINE('处理记录失败 - ID: ' || rec.xglc || ', 日期: ' || rec.djrq || ', 错误: ' || SQLERRM);
-- 如果错误太多,停止处理
IF v_error_count > 50 THEN
DBMS_OUTPUT.PUT_LINE('错误过多,停止处理');
EXIT;
END IF;
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
DBMS_OUTPUT.PUT_LINE('批量更新完成!');
DBMS_OUTPUT.PUT_LINE('成功更新: ' || v_count || ' 条记录');
DBMS_OUTPUT.PUT_LINE('失败记录: ' || v_error_count || ' 条记录');
-- 验证更新结果
DECLARE
v_updated_count NUMBER;
v_empty_count NUMBER;
BEGIN
SELECT COUNT(*) INTO v_updated_count
FROM uf_gcxx
WHERE gcbhz IS NOT NULL AND gcbhz != '';
SELECT COUNT(*) INTO v_empty_count
FROM uf_gcxx
WHERE gcbhz IS NULL OR gcbhz = '';
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
DBMS_OUTPUT.PUT_LINE('验证结果:');
DBMS_OUTPUT.PUT_LINE('已有编号的记录: ' || v_updated_count);
DBMS_OUTPUT.PUT_LINE('仍为空编号的记录: ' || v_empty_count);
END;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('批量更新过程出错: ' || SQLERRM);
ROLLBACK;
END;
--更新模块后使用update同步到流程表单
UPDATE formtable_main_1576 a
SET jsxmbh = (
SELECT gcbhz
FROM uf_gcxx
WHERE xglc = a.requestid
)
WHERE EXISTS (
SELECT 1
FROM uf_gcxx
WHERE xglc = a.requestid
);