重置Oracle Sequence以使MIN VALUE = 1并从1开始编号

时间:2015-05-11 02:34:46

标签: oracle sequence reset

我在重置Oracle序列时遇到问题,因为MIN VALUE = 1并且使用的下一个号码是1。

我已经按照这个问题的答案: How do I reset a sequence in Oracle?

   create or replace procedure reset_seq( p_seq_name in varchar2 ) is
        l_val number; 
begin
        execute immediate
        'select ' || p_seq_name || '.nextval from dual' INTO l_val;

        execute immediate
        'alter sequence ' || p_seq_name || ' increment by -' || l_val || 
                                                              ' minvalue 0';

        execute immediate
        'select ' || p_seq_name || '.nextval from dual' INTO l_val;

        execute immediate
        'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0'; 
end;

但是,问题是上面的代码重置了min值= 0的序列,下一个要使用的val是2.

重置完成后,是否可以将min_value = 1和nextval设置为1?

我试图设置它但是提到的错误大致如下:

  

当前值不能高于最小值。

谢谢!

1 个答案:

答案 0 :(得分:1)

  

重置完成后,是否可以将最小值设置为1,并将下一个val设置为1?

你可以分两步完成:

  • increment_by一个小于序列当前值的值。
  • 将increment_by重置为1.

逻辑是,你不应该将序列减少到零,因为你想要的 minvalue 1,所以, nextval不能小于minval

例如,

SQL> CREATE SEQUENCE s START WITH 20 MINVALUE 0 INCREMENT BY 1;

Sequence created.

SQL> SELECT s.nextval FROM dual;

   NEXTVAL
----------
        20

SQL> ALTER SEQUENCE s INCREMENT BY -19 MINVALUE 1;

Sequence altered.

SQL> SELECT s.nextval FROM dual;

   NEXTVAL
----------
         1

SQL> ALTER SEQUENCE s INCREMENT BY 1 MINVALUE 1;

Sequence altered.

SQL> SELECT s.nextval FROM dual;

   NEXTVAL
----------
         2

SQL> SELECT min_value, increment_by FROM user_sequences WHERE sequence_name='S';

 MIN_VALUE INCREMENT_BY
---------- ------------
         1            1

因此, min_value increment_by 现在分别重置1。在将 increment_by 重新设置为1之前, nextvalue 只能为1次。

所以,我没有看到你想要实现的任何实际用途。但是,它可以如上所示完成。

要在您的过程中实现上述逻辑,请执行以下操作:

<强>设置

SQL> DROP SEQUENCE S;

Sequence dropped.

SQL> CREATE SEQUENCE s START WITH 20 MINVALUE 0 INCREMENT BY 1;

Sequence created.

SQL> SELECT s.nextval FROM dual;

   NEXTVAL
----------
        20

程序修改为:

SQL> CREATE OR REPLACE PROCEDURE reset_seq(
  2      p_seq_name IN VARCHAR2 )
  3  IS
  4    l_val NUMBER;
  5  BEGIN
  6    EXECUTE IMMEDIATE 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
  7    l_val := l_val - 1;
  8    dbms_output.put_line('l_val = '||l_val);
  9    EXECUTE IMMEDIATE 'alter sequence ' ||
 10                       p_seq_name || ' increment by -' || l_val || ' minvalue 1';
 11    EXECUTE IMMEDIATE 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
 12    dbms_output.put_line('1st Nextval is '||l_val);
 13    EXECUTE IMMEDIATE 'alter sequence ' || p_seq_name ||
 14                      ' increment by 1 MINVALUE 1';
 15    EXECUTE IMMEDIATE 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
 16    dbms_output.put_line('2nd Nextval is '||l_val);
 17  END;
 18  /

Procedure created.

SQL> SET serveroutput ON
SQL> EXEC reset_seq('S');
l_val = 20
1st Nextval is 1
2nd Nextval is 2

PL/SQL procedure successfully completed.

SQL>
SQL> SELECT min_value, increment_by FROM user_sequences where sequence_name='S';

 MIN_VALUE INCREMENT_BY
---------- ------------
         1            1

正如我所说,我没有看到任何实际用途。您的 nextval 实际上只能从2使用。如果是1,您需要再次执行 ALTER SEQUENCE ,将 increment_by 重置为1