Oracle
 sql >> Baza danych >  >> RDS >> Oracle

12c kolumny TOŻSAMOŚĆ

Mieszkam i pracuję w pobliżu placówki Microsoft. W związku z tym wielu naszych obecnych pracowników to byli pracownicy firmy Microsoft, którzy wywodzą się z SQL Server. SQL Server umożliwia tworzenie tabeli z kolumną IDENTITY. Oracle 12c pozwala teraz zrobić to samo. Powinno to pomóc tym, którzy przechodzą z SQL Server na Oracle. Pozwala także firmie łatwiej przenieść aplikację z SQL Server lub dowolnej innej bazy danych, która pozwala na kolumnę IDENTITY, do Oracle.

Najpierw stworzę tabelę z kolumną IDENTITY i wypełnię ją kilkoma wierszami danych.

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.
 

Zauważ, że nie wstawiłem żadnych wartości do kolumny ID. Teraz przeprowadźmy zapytanie do tabeli.

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

Jak widać, moje wartości ID zostały dodane zgodnie z oczekiwaniami. Podczas tworzenia tabeli zdefiniowałem tę kolumnę IDENTITY za pomocą:    GENERATED BY DEFAULT ON NULL

Klauzula BY DEFAULT oznacza, że ​​Oracle automatycznie przypisze następną wartość w sekwencji, jeśli pominiesz ją w instrukcji INSERT. Jeśli ją uwzględnisz, Oracle użyje określonej przez Ciebie wartości. Rozważ to:

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
 

Jak widać, ponieważ wyraźnie określiłem ID=4 i Oracle przepuściło tę wartość. Co się stanie, gdy spróbuję wstawić następną wartość, która powinna wynosić 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
Powyższe zadziałało zgodnie z oczekiwaniami. Użyto następnej dostępnej wartości identyfikatora. Ale czy następne wstawienie użyje „4” czy „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
O o! Zduplikowana wartość była dozwolona. Spodziewałem się, że zostanie utworzone ograniczenie klucza podstawowego, aby wymusić koncepcję wartości „tożsamości”, ale tak się nie dzieje. Jakie ograniczenia istnieją?
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
Tak więc jedynym ograniczeniem jest ograniczenie sprawdzające NOT NULL. Teraz usuńmy ten ostatni wiersz i dodajmy ograniczenie 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.
Teraz upewnię się, że mam trochę danych do przetestowania.
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.
Więc wyraźnie dodałem ID=6. Jeśli tak jest, gdy jawnie dodałem ID=4, moja następna wstawka spróbuje użyć ID=6, a przy ograniczeniu PK zostanie zgłoszony wyjątek.
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
Morał tej historii jest taki, że jeśli użyjesz opcji ON DEFAULT, bądź przygotowany na radzenie sobie z kolizją wartości tożsamości. Wartość domyślna to ZAWSZE zamiast WŁĄCZONE DOMYŚLNIE. W przypadku opcji ALWAYS Oracle zawsze będzie używać generatora numerów sekwencyjnych. Jeśli spróbujesz określić wartość identyfikatora, wystąpi wyjątek.
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
Widok *_TAB_COLUMNS może pokazać, które kolumny w tabeli są kolumnami IDENTITY.
SQL> select column_name,identity_column from user_tab_columns where table_name='TEST_TAB';
COLUMN_NAME     IDE
--------------- ---
ID              YES
VAL             NO
Jeśli używasz kolumny IDENTITY w tabelach, pamiętaj o przeprowadzeniu testów, aby upewnić się, że rozumiesz, że działa ona poprawnie w Twojej aplikacji. Byłem zaskoczony, że ograniczenie PK lub UNIQUE nie zostało automatycznie uwzględnione, co pozwoliło mi dodać zduplikowaną wartość.
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Problem z hibernacją z wyzwalaczem Oracle do generowania identyfikatora z sekwencji

  2. jak używać xmltable w Oracle?

  3. Używanie widoku bez klucza podstawowego z Entity

  4. Wprowadzenie do pakietów PL/SQL w bazie danych Oracle

  5. Wdrażanie blokowania optymistycznego w Oracle