Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Perlu mengatur ulang nilai urutan di Oracle

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:

  1. Pertama, cari tahu berapa nilai id (urutan) maksimum di tabel Anda.
  2. 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:

  1. Menentukan perbedaan antara id maksimum di tabel Anda dan nilai urutan saat ini.
  2. Mengubah urutan menjadi bertambah dengan angka negatif ini
  3. 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>


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Java - temukan penyebab pertama pengecualian

  2. Oracle PL/SQL - Koleksi (Tabel Bersarang)

  3. Apakah ada Cara untuk menggunakan Linq ke Oracle

  4. Addnode resolv.conf Kegagalan

  5. Bagaimana batas waktu kueri JDBC Oracle diterapkan?