Oracle数据库数字范围拆分需求咨询:固定拆分与子范围拆分
数字范围拆分解决方案(需求2实现)
实现思路
针对从数据库大范围内拆分指定子范围的需求,核心逻辑为:
- 定位包含目标子范围的原始记录
- 删除原始记录
- 插入拆分后的有效片段(仅保留实际存在的前剩余段、目标子范围、后剩余段)
表结构回顾
CREATE TABLE table1 ( Code VARCHAR2(10), DN_from NUMBER, DN_to NUMBER, PRIMARY KEY (Code, DN_from, DN_to) -- 建议添加唯一约束避免重复/重叠范围 );
示例初始数据:
| Code | DN_from | DN_to |
|---|---|---|
| A | 1 | 10000 |
| A | 10001 | 20000 |
| A | 20001 | 30000 |
| B | 1 | 10000 |
| B | 10001 | 20000 |
具体实现(PL/SQL存储过程)
封装为存储过程,接收目标Code、拆分起始值、拆分结束值三个参数,确保事务原子性:
CREATE OR REPLACE PROCEDURE split_range( p_code IN VARCHAR2, p_split_from IN NUMBER, p_split_to IN NUMBER ) AS v_original_from NUMBER; v_original_to NUMBER; BEGIN -- 1. 定位并锁定目标原始记录,防止并发修改 SELECT DN_from, DN_to INTO v_original_from, v_original_to FROM table1 WHERE code = p_code AND DN_from <= p_split_from AND DN_to >= p_split_to FOR UPDATE; -- 2. 删除原始记录 DELETE FROM table1 WHERE code = p_code AND DN_from = v_original_from AND DN_to = v_original_to; -- 3. 插入拆分后的有效片段 -- 插入前剩余段(仅当原始起始值 < 拆分起始值时) IF v_original_from < p_split_from THEN INSERT INTO table1 (Code, DN_from, DN_to) VALUES (p_code, v_original_from, p_split_from - 1); END IF; -- 插入目标子范围(必插) INSERT INTO table1 (Code, DN_from, DN_to) VALUES (p_code, p_split_from, p_split_to); -- 插入后剩余段(仅当原始结束值 > 拆分结束值时) IF v_original_to > p_split_to THEN INSERT INTO table1 (Code, DN_from, DN_to) VALUES (p_code, p_split_to + 1, v_original_to); END IF; COMMIT; EXCEPTION WHEN NO_DATA_FOUND THEN ROLLBACK; RAISE_APPLICATION_ERROR(-20001, '未找到包含指定子范围的记录'); WHEN TOO_MANY_ROWS THEN ROLLBACK; RAISE_APPLICATION_ERROR(-20002, '找到多条匹配记录,请检查数据'); WHEN OTHERS THEN ROLLBACK; RAISE; END; /
测试示例
示例1:输入Code=A,拆分范围1-100
执行语句:
EXEC split_range('A', 1, 100);
拆分后对应记录变为:
| Code | DN_from | DN_to |
|---|---|---|
| A | 1 | 100 |
| A | 101 | 10000 |
示例2:输入Code=A,拆分范围1000-10000
执行语句:
EXEC split_range('A', 1000, 10000);
拆分后对应记录变为:
| Code | DN_from | DN_to |
|---|---|---|
| A | 1 | 999 |
| A | 1000 | 10000 |
示例3:输入Code=A,拆分范围1-1
执行语句:
EXEC split_range('A', 1, 1);
拆分后对应记录变为:
| Code | DN_from | DN_to |
|---|---|---|
| A | 1 | 1 |
| A | 2 | 10000 |
注意事项
- 必须确保
table1中同一Code下的范围无重叠、无间隙,否则拆分逻辑可能出错 - 存储过程使用
FOR UPDATE锁定记录,避免并发修改导致数据不一致 - 异常处理保证事务原子性,出错时自动回滚所有操作
内容的提问来源于stack exchange,提问作者abhid89
相关产品推荐
相关产品推荐

