Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Cần đặt lại giá trị của chuỗi trong Oracle

Những lý do tại sao bạn không nên đặt lại giá trị nếu nó đang được sử dụng:

Điều gì xảy ra nếu bạn có 20 bản ghi và xóa bản ghi 5-10? Bạn có một khoảng trống ở giữa mà việc thiết lập lại trình tự sẽ không giải quyết được. Các chuỗi sẽ không bao giờ tạo ra một chuỗi số không có khoảng trống, một 1, 2 .. n .

Nếu bạn gọi .nextval và không sử dụng giá trị mà nó đã biến mất . Bạn có định bỏ và tạo lại trình tự không? Nếu bạn bắt đầu chèn và hủy nó và Oracle khôi phục lại những gì bạn đã thực hiện thì các giá trị đó đã biến mất . Nếu bạn đặt nocache sau đó bạn sẽ có ít khoảng trống hơn nhưng với một cái giá phải trả cho hiệu suất; Nó có đáng không?

Bộ nhớ cache của bạn phải được đặt thành số lần chèn bạn muốn thực hiện bất kỳ lúc nào trên tất cả các phiên để tránh mọi vấn đề về hiệu suất. Các chuỗi được thiết kế để cung cấp một cách rất nhanh chóng, có thể mở rộng để tạo khóa thay thế mà không cần bất kỳ ổ khóa nào, v.v. không để tạo lại tập hợp các số nguyên dương.

Vào cuối ngày, nó sẽ không thành vấn đề dù là nhỏ nhất. Nếu bạn đang dựa vào một chuỗi không bị gián đoạn làm khóa của bảng thì bạn gặp sự cố với dữ liệu của mình chứ không phải chuỗi.

Trả lời câu hỏi:

Để thực sự trả lời câu hỏi của bạn, bạn cần phải:

  1. Trước hết, hãy tìm hiểu giá trị id (trình tự) tối đa trong bảng của bạn là bao nhiêu.
  2. Sau đó, thả và tạo lại trình tự.

Tìm giá trị tối đa có nghĩa là bạn cần phải tạo lại chuỗi động với chi phí của một lần truy cập khác để đạt được hiệu suất.

Nếu bạn cố gắng chèn thứ gì đó vào bảng của mình trong khi điều này đang xảy ra, nó sẽ không thành công và có thể làm mất hiệu lực của bất kỳ trình kích hoạt hoặc đối tượng nào khác sử dụng trình tự:

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;
/

Như tôi đã nói điều này không được khuyến khích và bạn chỉ nên bỏ qua bất kỳ khoảng trống nào.

Cập nhật - hay còn gọi là Câu trả lời hay hơn Cảm ơn Jeffrey Kemp:

Trái ngược với khuyến nghị của tài liệu, như Jeffrey Kemp đã đề xuất trong các nhận xét, một cách để thực hiện điều này mà không thả và tạo lại trình tự.

Cụ thể, bởi:

  1. Tìm ra sự khác biệt giữa id tối đa trong bảng của bạn và giá trị hiện tại của chuỗi.
  2. Thay đổi trình tự để tăng dần theo số âm này
  3. Thay đổi trình tự để tăng thêm 1 lần nữa.

Lợi ích của việc này là đối tượng vẫn tồn tại và các kích hoạt, trợ cấp, v.v. vẫn được duy trì. Nhược điểm, như tôi thấy, là nếu một phiên khác tăng số âm này cùng lúc với phiên của bạn, bạn có thể quay lại quá xa.

Đây là một minh chứng:

Thiết lập kiểm tra:

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.

Hoàn nguyên trình tự

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. 50 Sắc thái của Kỳ thi Chứng chỉ Cơ sở dữ liệu Oracle

  2. Trình kiểm tra cú pháp SQL trực tuyến phù hợp với nhiều cơ sở dữ liệu

  3. % Type có nghĩa là gì trong Oracle sql?

  4. OLAP mô phỏng

  5. Hàm DECOMPOSE () trong Oracle