1、背景
1.1 背景
项目中有5个序列发生器(分别为:seq1、seq2、seq3、seq4、seq5),各序列发生的作用是产生[10000,19999)、[20000,29999)、[30000,39999)、[40000,49999)、[50000,59999)的数值。创建序列的DDL如下:
复制代码1
2
3
4
5
6
7
8
9CREATE SEQUENCE seq1 START WITH 10001 MAXVALUE 19999 MINVALUE 10001 increment by 1 NOCYCLE NOCACHE ORDER;
其他的同样,区别只是开始值不同
1.2 问题
目前每天晚上00:00有定时任务,作用是删掉序列发生器,然后重建,保证每天的序列发生器是从起始值开始的。
最近一段时间偶尔出问题,经查询,重置序列发生器的定时任务在运行时,有其他定时任务正在使用这些序列发生器,从而导致定时任务失败。
因此,现场要求:既要重置序列发生器,又避免发生异常。
所以,采用非重建的方式重置序列发生器
2、解决方案
创建procedure,如下:
复制代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40/* 创建人:郑林 2017-8-30 方法说明:重置序列发生器 参数说明:v_seqname序列发生器名称;v_max_value序列的最大值 其他说明:cache按默认值处理 */ create or replace procedure seq_reset(v_seqname varchar2,v_max_value number) as n number(10); tsql varchar2(100); begin --1、设置为nocahe(防止出现ora-04013错误) execute immediate 'alter sequence '|| v_seqname ||' NOCACHE'; --2、获取序列的当前值 execute immediate 'select '|| v_seqname ||'.nextval from dual' into n; n :=v_max_value-n; --3、更改步长 tsql := 'alter sequence '|| v_seqname ||' increment by ' || n; execute immediate tsql; --4、获取当前值 begin execute immediate 'select '|| v_seqname ||'.nextval from dual' into n; exception when others then if sqlcode='-8004' then tsql:='alter sequence '||v_seqname||' increment by 1'; execute immediate tsql; end if; end; --5、恢复步长 tsql := 'alter sequence ' || v_seqname ||' increment by 1'; execute immediate tsql; --6、恢复cache execute immediate 'alter sequence '|| v_seqname ||' CACHE 20'; end seq_reset;
参数中:v_seqname 为序列发生器的名称;v_max_value 为序列发生器的最大值
这样,重写定时任务,便可解决当前问题
复制代码1
2
3SQL> set serveroutput on; SQL> exec seq_reset('SRXS001',19999); PL/SQL procedure successfully completed
3、参考资料
1、动态SQL,参考:动态SQL资料链接
2、非重建方式,参考:非重建的链接
4、C#调用procedure
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58//获取设定的数据 private int executeProcedure() { int result = 1; //获取数据库连接 OracleConnection conn = DataBaseContext.GetSequenceOracleConnection(); OracleCommand command = new OracleCommand(); try { command.Connection = conn; command.CommandType = CommandType.StoredProcedure; List<SeqModel> seqList = getSeqList(); //完成执行procedure的方法 seqList.ForEach(t => { result = result * executeProcedure(t.SeqName, t.MaxValue, command); }); conn.Close(); return result; } catch (System.Exception ex) { SysLog.LogWrite("pharmacy.log", ex); return -1; } finally { if (conn != null) conn.Close(); } } //执行procedure的方法 private int executeProcedure(string sequence_name, int max_value,OracleCommand command) { int execute_result = 0; try { command.CommandText = "seq_reset"; command.Parameters.Clear(); command.Parameters.Add("v_seqname", OracleDbType.Varchar2).Direction = ParameterDirection.Input; command.Parameters["v_seqname"].Value = sequence_name; command.Parameters.Add("v_max_value", OracleDbType.Int32).Direction = ParameterDirection.Input; command.Parameters["v_max_value"].Value = max_value; execute_result = command.ExecuteNonQuery(); return execute_result; } catch (System.Exception ex) { SysLog.LogWrite("pharmacy.log", ex); return -1; } }
最后
以上就是动人手套最近收集整理的关于Oracle重置序列发生器(非重建)的全部内容,更多相关Oracle重置序列发生器(非重建)内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复