Grunde til, hvorfor du ikke bør nulstille værdien, hvis den bliver brugt:
Hvad sker der, hvis du har 20 poster og sletter post 5-10? Du har et hul i midten, som ikke løses ved at genindstille sekvensen. Sekvenser vil aldrig generere en mellemrumsfri række af tal, en perfekt 1, 2 .. n .
Hvis du ringer til .nextval
og brug ikke den værdi, det er bort . Vil du slippe og genskabe sekvensen? Hvis du starter en indsættelse og annullerer den, og Oracle ruller tilbage, hvad du har gjort, er disse værdier forsvundet . Hvis du indstiller nocache
så vil du have færre huller, men til en pris af et hit til ydeevnen; er det det værd?
Din cache skal indstilles til det antal inserts, du forventer at gøre på ethvert tidspunkt i alle sessioner for at undgå problemer med ydeevnen. Sekvenser er designet til at give en meget hurtig, skalerbar måde at skabe en surrogatnøgle uden nogen låse osv. ikke at genskabe sættet af positive heltal.
I slutningen af dagen burde det ikke betyde det mindste. Hvis du stoler på en ubrudt sekvens som nøglen til din tabel, har du et problem med dine data snarere end sekvenser.
Besvarelse af spørgsmålet:
For rent faktisk at besvare dit spørgsmål skal du:
- Først skal du finde ud af, hvad den maksimale id-værdi (sekvens) i din tabel er.
- Slip derefter og genskab sekvensen.
At finde den maksimale værdi betyder, at du bliver nødt til at genskabe sekvensen dynamisk på bekostning af endnu et hit til ydeevnen.
Hvis du forsøger at indsætte noget i din tabel, mens dette sker, vil det mislykkes og kan ugyldiggøre eventuelle triggere eller andre objekter, der bruger sekvensen:
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;
/
Som jeg siger, anbefales dette ikke, og du bør bare ignorere eventuelle huller.
Opdatering - aka et bedre svar takket være Jeffrey Kemp:
I modsætning til dokumentationens anbefaling er der, som Jeffrey Kemp foreslog i kommentarerne, en måde at gøre dette uden på slippe og genskabe sekvensen.
Nemlig af:
- Udregning af forskellen mellem det maksimale
id
i din tabel og den aktuelle værdi af sekvensen. - Ændring af rækkefølgen til at stige med dette negative tal
- Ændring af rækkefølgen til at øges med 1 igen.
Fordelene ved dette er, at objektet stadig eksisterer så og triggere, bevillinger osv. stadig opretholdes. Ulempen, som jeg ser det, er, at hvis en anden session stiger med dette negative tal på samme tid som din, kan du gå for langt tilbage.
Her er en demonstration:
Konfigurer testen:
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
----------
20
SQL>
SQL> delete from tmp_test where id > 15;
5 rows deleted.
SQL> commit;
Commit complete.
Tilbagestil rækkefølgen
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
----------
15
SQL>