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

12c cột IDENTITY

Tôi sống và làm việc gần một cơ sở của Microsoft. Do đó, nhiều nhân viên hiện tại của chúng tôi là cựu nhân viên của Microsoft đến từ nền tảng SQL Server. SQL Server cho phép bạn tạo một bảng có cột IDENTITY. Oracle 12c giờ đây cho phép bạn làm điều tương tự. Điều này sẽ giúp những người đang thực hiện chuyển đổi từ SQL Server sang Oracle. Nó cũng cho phép một công ty dễ dàng chuyển ứng dụng từ SQL Server hoặc bất kỳ cơ sở dữ liệu nào khác cho phép cột IDENTITY sang Oracle.

Đầu tiên, tôi sẽ tạo một bảng với cột IDENTITY và điền vào nó một số hàng dữ liệu.

SQL> create table test_tab (
2      id   NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,  
3      val  VARCHAR2(20));
Table created.
SQL> insert into test_tab (val) values ('my first row');
1 row created.
SQL> insert into test_tab (val) values ('my second row');
1 row created.
SQL> commit;
Commit complete.
 

Lưu ý rằng tôi đã không chèn bất kỳ giá trị nào vào cột ID. Bây giờ, hãy truy vấn bảng.

SQL> select * from test_tab;
ID VAL
---------- --------------------
1 my first row
2 my second row
 

Như bạn có thể thấy, các giá trị ID của tôi đã được thêm vào như bạn có thể mong đợi. Trong quá trình tạo bảng của mình, tôi đã xác định cột IDENTITY này với:ĐƯỢC TẠO THEO DEFAULT ON NULL

Mệnh đề BY DEFAULT có nghĩa là Oracle sẽ tự động gán giá trị tiếp theo trong chuỗi nếu bạn bỏ qua nó trong câu lệnh INSERT của mình. Nếu bạn bao gồm nó, thì Oracle sẽ sử dụng giá trị được chỉ định của bạn. Hãy xem xét điều này:

SQL> insert into test_tab values (4,'specified ID=4');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test_tab;
        ID VAL
---------- --------------------
         1 my first row
         2 my second row
         4 specified ID=4
 

Như bạn có thể thấy, bởi vì tôi đã tuyên bố rõ ràng ID =4 và Oracle để giá trị đó đi qua. Điều gì xảy ra khi tôi cố gắng chèn giá trị tiếp theo, giá trị này phải là 3?

SQL> insert into test_tab (val) values ('my row after ID=4');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test_tab;
        ID VAL
---------- --------------------
         1 my first row
         2 my second row
         4 specified ID=4
         3 my row after ID=4
Ở trên hoạt động như tôi mong đợi. Giá trị ID có sẵn tiếp theo đã được sử dụng. Nhưng lần chèn tiếp theo sẽ sử dụng '4' hoặc '5'?
SQL>  insert into test_tab (val) values ('my fifth row');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test_tab;
        ID VAL
---------- --------------------
         1 my first row
         2 my second row
         4 specified ID=4
         3 my row after ID=4
         4 my fifth row
Ồ! Giá trị trùng lặp đã được cho phép. Tôi đã mong đợi một ràng buộc Khóa chính được tạo để thực thi khái niệm về giá trị “danh tính”, nhưng điều đó không xảy ra. Ràng buộc nào tồn tại?
SQL> select constraint_name,constraint_type,table_name,search_condition from user_constraints;
CONSTRAINT_NAME                C TABLE_NAME
------------------------------ - ------------------------------
SEARCH_CONDITION
--------------------------------------------------------------------------------
SYS_C004978                    C TEST_TAB
"ID" IS NOT NULL
Vì vậy, ràng buộc duy nhất là một ràng buộc kiểm tra NOT NULL. Bây giờ chúng ta hãy xóa hàng cuối cùng đó và thêm một ràng buộc PK.
SQL> delete from test_tab where val='my fifth row';
1 row deleted.
SQL> commit;
Commit complete.
SQL> alter table test_tab add constraint test_tab_pk primary key (id);
Table altered.
Bây giờ tôi sẽ đảm bảo rằng tôi có một số dữ liệu để kiểm tra với.
SQL> insert into test_tab (val) values ('after pk constraint');
1 row created.
SQL> insert into test_tab (id,val) values (6,'explicitly set id=6');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test_tab;
        ID VAL
---------- --------------------
         1 my first row
         2 my second row
         4 specified ID=4
         3 my row after ID=4
         5 after pk constraint
         6 explicitly set id=6
6 rows selected.
Vì vậy, tôi đã thêm ID =6 một cách rõ ràng. Nếu điều này giống như khi tôi thêm ID =4 một cách rõ ràng, thì lần chèn tiếp theo của tôi sẽ cố gắng sử dụng ID =6 và khi có ràng buộc PK, một ngoại lệ sẽ được đưa ra.
SQL> insert into test_tab (val) values ('after ID=6');
insert into test_tab (val) values ('after ID=6')
*
ERROR at line 1:
ORA-00001: unique constraint (PEASLAND.TEST_TAB_PK) violated
Vì vậy, đạo lý của câu chuyện là nếu bạn sử dụng TRÊN MẶT ĐỊNH, hãy chuẩn bị để xử lý các va chạm về giá trị bản sắc. Mặc định là LUÔN thay vì BẬT MẶC ĐỊNH. Với LUÔN LUÔN, Oracle sẽ luôn sử dụng trình tạo số thứ tự. Nếu bạn cố gắng chỉ định một giá trị id, một ngoại lệ sẽ xảy ra.
SQL> create table test_tab2(id number generated always as identity, val varchar2(20));
Table created.
SQL> insert into test_tab2(id,val) values (1,'first row');
insert into test_tab2(id,val) values (1,'first row')
                      *
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column
Chế độ xem * _TAB_COLUMNS có thể hiển thị cho bạn những cột nào trong bảng là cột IDENTITY.
SQL> select column_name,identity_column from user_tab_columns where table_name='TEST_TAB';
COLUMN_NAME     IDE
--------------- ---
ID              YES
VAL             NO
Nếu bạn sử dụng cột IDENTITY trong các bảng của mình, hãy cẩn thận kiểm tra để đảm bảo bạn hiểu rằng nó hoạt động chính xác cho ứng dụng của bạn. Tôi ngạc nhiên rằng ràng buộc PK hoặc UNIQUE không được tự động đưa vào mà cho phép tôi thêm một giá trị trùng lặp.
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách tìm Lịch sử chờ đợi của phiên Oracle

  2. Tiếp tục Chèn trong Oracle khi ngoại lệ được nâng lên

  3. Mệnh đề WHERE có điều kiện với câu lệnh CASE trong Oracle

  4. CURRENT_TIMESTAMP và SYSDATE khác nhau trong tiên tri

  5. Chính xác thì dấu ngoặc kép xung quanh tên bảng làm gì?