Alasan mengapa Anda tidak perlu menyetel ulang nilai jika sedang digunakan:
Apa yang terjadi jika Anda memiliki 20 catatan dan menghapus catatan 5-10? Anda memiliki celah di tengah yang mengatur ulang urutan tidak akan menyelesaikannya. Urutan tidak akan tidak pernah menghasilkan urutan angka yang bebas celah, 1, 2 .. n . yang sempurna .
Jika Anda memanggil .nextval
dan jangan gunakan nilai yang hilang . Apakah Anda akan menjatuhkan dan membuat ulang urutannya? Jika Anda memulai penyisipan dan membatalkannya dan Oracle mengembalikan apa yang telah Anda lakukan, nilai-nilai itu hilang . Jika Anda mengatur nocache
maka Anda akan memiliki lebih sedikit kesenjangan tetapi dengan mengorbankan kinerja; Apakah itu layak?
Cache Anda harus disetel ke jumlah penyisipan yang Anda harapkan dilakukan pada satu waktu di semua sesi untuk menghindari masalah kinerja. Urutan dirancang untuk menyediakan cara yang sangat cepat dan terukur untuk membuat kunci pengganti tanpa kunci apa pun, dll tidak untuk membuat ulang himpunan bilangan bulat positif.
Pada akhirnya, itu seharusnya tidak menjadi masalah sedikit pun. Jika Anda mengandalkan urutan yang tidak terputus sebagai kunci tabel Anda, maka Anda memiliki masalah dengan data Anda daripada urutan.
Menjawab pertanyaan:
Untuk benar-benar menjawab pertanyaan Anda, Anda perlu:
- Pertama, cari tahu berapa nilai id (urutan) maksimum di tabel Anda.
- Kemudian lepaskan dan buat ulang urutannya.
Menemukan nilai maksimum berarti Anda harus membuat ulang urutan secara dinamis dengan mengorbankan hit lain untuk kinerja.
Jika Anda mencoba memasukkan sesuatu ke dalam tabel Anda saat ini terjadi, itu akan gagal, dan dapat membatalkan pemicu atau objek lain apa pun yang menggunakan urutan:
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;
/
Seperti yang saya katakan, ini tidak disarankan dan Anda harus mengabaikan celah apa pun.
Pembaruan - alias Jawaban yang Lebih Baik Terima kasih kepada Jeffrey Kemp:
Bertentangan dengan rekomendasi dokumentasi, seperti yang disarankan Jeffrey Kemp di komentar, ada cara untuk melakukan ini tanpa menjatuhkan dan menciptakan kembali urutannya.
Yaitu, oleh:
- Menentukan perbedaan antara
id
maksimum di tabel Anda dan nilai urutan saat ini. - Mengubah urutan menjadi bertambah dengan angka negatif ini
- Mengubah urutan menjadi bertambah 1 lagi.
Manfaat dari ini adalah bahwa objek masih ada dan pemicu, hibah dll masih dipertahankan. Kelemahannya, seperti yang saya lihat, adalah jika sesi lain bertambah dengan angka negatif ini pada saat yang sama dengan sesi Anda, Anda bisa mundur terlalu jauh.
Berikut demonstrasinya:
Siapkan pengujian:
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.
Kembalikan urutannya
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>