栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

需要在Oracle中重置序列的值

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

需要在Oracle中重置序列的值

如果使用该值,则不应重置该值的原因:

如果您有20条记录并删除5-10条记录会怎样?中间有一个缝隙,无法重新设置序列。序列 永远不会
生成无间隙的数字序列
,即完美的
1、2 .. n

如果您调用

.nextval
并且不使用该值,那么它就 消失了 。您要删除并重新创建序列吗?如果开始插入并取消插入,Oracle
将回滚所做的操作,这些值将
消失 。如果设置,
nocache
则差距将减少,但会降低性能。这值得么?

您的缓存应该设置为您希望
在所有会话中
一次执行的插入次数,以避免任何性能问题。序列旨在提供一种非常快速,可扩展的方式来创建代理密钥,而无需任何锁等, 以免 重新生成正整数集。

归根结底,这丝毫没有关系。如果您将不间断的序列作为表的键,则您的数据而不是序列有问题。


回答问题:

要真正回答您的问题,您需要:

  1. 首先,找出表中的最大id(序列)值。
  2. 然后放下并重新创建序列。

找到最大值意味着您需要动态地重新创建序列,而又要牺牲性能。

如果您尝试在此期间向表中插入某些内容,它将失败,并且可能会使使用该序列的任何触发器或其他对象无效:

declare   l_max_value number;begin   select max(id)     into l_max_value     from my_table;   execute immediate 'drop sequence my_sequence_name';   -- nocache is not recommended if you are inserting more than   -- one row at a time, or inserting with any speed at all.   execute immediate 'create sequence my_sequence_name     start with ' || l_max_value|| ' increment by 1     nomaxvalue     nocycle     nocache';end;/

正如我所说,不建议这样做,您应该忽略任何差距。


更新-又名更好的答案感谢[Jeffrey Kemp](https://stackoverflow.com/users/103295/jeffrey-

kemp):

正如杰弗里·肯普(Jeffrey Kemp)在评论中所建议的那样,有一种与文档建议相反的方法,该方法 无需 删除并重新创建序列即可。

即,通过:

  1. 计算
    id
    表中的最大值与序列的当前值之间的差。
  2. 更改顺序以此负数递增
  3. 更改顺序以再次增加1。

这样做的好处是对象仍然存在,并且触发器,授权等也得以维护。不利的一面是,如果另一个会话与您的会话同时增加此负数,则可能会返回得太远。

这是一个示范:

设置测试:

SQL> create sequence test_seq  2   start with 1  3   increment by 1  4   nomaxvalue  5   nocycle  6   nocache;Sequence created.SQL>SQL> create table tmp_test ( id number(16) );Table created.SQL>SQL> declare  2     l_nextval number;  3  begin  4  5    for i in 1 .. 20 loop  6       insert into tmp_test values ( test_seq.nextval );  7    end loop;  8  9  end; 10  /PL/SQL procedure successfully completed.SQL>SQL> select test_seq.currval from dual;   CURRVAL----------        20SQL>SQL> delete from tmp_test where id > 15;5 rows deleted.SQL> commit;Commit complete.

还原顺序

SQL>SQL> declare  2  3     l_max_id number;  4     l_max_seq number;  5  6  begin  7  8     -- Get the maximum ID  9     select max(id) into l_max_id 10       from tmp_test; 11 12     -- Get the current sequence value; 13     select test_seq.currval into l_max_seq 14       from dual; 15 16     -- Alter the sequence to increment by the difference ( -5 in this case ). 17     execute immediate 'alter sequence test_seq 18    increment by ' || ( l_max_id - l_max_seq ); 19 20     -- 'increment' by -5 21     select test_seq.nextval into l_max_seq 22       from dual; 23 24     -- Change the sequence back to normal 25     execute immediate 'alter sequence test_seq 26    increment by 1'; 27 28  end; 29  /PL/SQL procedure successfully completed.SQL>SQL> select test_seq.currval from dual;   CURRVAL----------        15SQL>


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/412870.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号