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

Cách triển khai trình tự đa chiều

Cách duy nhất để làm điều này là sử dụng bảng điều khiển mã ...

create table code_control
    (year number(4,0) not null
     , type varchar2(1) not null
     , last_number number(38,0) default 1 not null
     , primary key (year,type)
    )
organization index
/   

... được duy trì như thế này ...

create or replace function get_next_number
    (p_year in number, p_type in varchar2)
    return number
is
    pragma autonomous_transaction;
    cursor cur_cc is
        select last_number + 1
        from code_control cc
        where cc.year= p_year
        and cc.type = p_type
        for update of last_number;
    next_number number;
begin
    open cur_cc;
    fetch cur_cc into next_number;
    if cur_cc%found then
        update code_control
        set last_number = next_number
        where current of cur_cc;
    else
        insert into code_control (year,type)
        values (p_year, p_type)
        returning last_number into next_number;
    end if;    
    commit;
    return next_number;
end;
/

Điều quan trọng là CHỌN ... ĐỂ CẬP NHẬT. Khóa bi quan đảm bảo tính duy nhất trong môi trường nhiều người dùng. PRAGMA đảm bảo rằng việc duy trì code_control không gây ô nhiễm cho giao dịch rộng lớn hơn. Nó cho phép chúng ta gọi hàm trong một trình kích hoạt mà không có deadlock.

Đây là một bảng có khóa giống như của bạn:

create table t42
     (year number(4,0) not null
     , type varchar2(1) not null
     , id number(38,0) 
     , primary key (year,type, id)
)
/
create or replace trigger t42_trg
    before insert on t42 for each row
begin
    :new.id := get_next_number(:new.year, :new.type);
end;
/

Không có gì trong tay áo của tôi trước khi tôi điền t42 :

SQL> select * from code_control;

no rows selected

SQL> select * from t42;

no rows selected

SQL> insert into t42 (year, type) values (2016, 'A');

1 row created.

SQL> insert into t42 (year, type) values (2016, 'A');

1 row created.

SQL> insert into t42 (year, type) values (2016, 'A');

1 row created.

SQL> insert into t42 (year, type) values (2016, 'B');

1 row created.

SQL> insert into t42 (year, type) values (2016, 'A');

1 row created.

SQL> insert into t42 (year, type) values (2017, 'A');

1 row created.

SQL> select * from t42;

      YEAR T         ID
---------- - ----------
      2016 A          1
      2016 A          2
      2016 A          3
      2016 A          4
      2016 B          1
      2017 A          1

6 rows selected.

SQL> select * from code_control;

      YEAR T LAST_NUMBER
---------- - -----------
      2016 A           4
      2016 B           1
      2017 A           1

SQL> 

Vì vậy, sự phản đối rõ ràng đối với việc triển khai này là khả năng mở rộng. Việc chèn các giao dịch được tuần tự hóa trên code_control bàn. Điều đó hoàn toàn đúng. Tuy nhiên, khóa được giữ trong thời gian ngắn nhất có thể, vì vậy điều này sẽ không thành vấn đề ngay cả khi t42 bảng được điền nhiều lần trong một giây.

Tuy nhiên, nếu bảng có số lượng lớn các chèn đồng thời thì việc khóa có thể trở thành một vấn đề. Điều quan trọng là bảng có đủ các vị trí Giao dịch quan tâm (INITRANS, MAXTRANS) để đáp ứng các nhu cầu đồng thời. Nhưng các hệ thống rất bận rộn có thể cần triển khai thông minh hơn (có thể tạo ID theo lô); nếu không thì từ bỏ khóa ghép để ủng hộ một trình tự (vì các trình tự mở rộng quy mô trong môi trường nhiều người dùng).




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle SQL - Mệnh đề IN hiển thị tất cả bản ghi được đưa ra trong điều kiện IN ngay cả khi dữ liệu không có trong bảng

  2. REGEXP_COUNT () Hàm trong Oracle

  3. Kích hoạt cập nhật lỗi clob

  4. Đệ quy Oracle SQL để tìm trường hợp đầu tiên của giá trị cột không null

  5. cx_Oracle - Tải DLL không thành công:% 1 không phải là ứng dụng Win32 hợp lệ. con trăn