sql >> Database >  >> RDS >> Oracle

12c IDENTITEIT kolommen

Ik woon en werk dicht bij een Microsoft-faciliteit. Als zodanig zijn veel van onze huidige medewerkers voormalige Microsoft-medewerkers met een SQL Server-achtergrond. Met SQL Server kunt u een tabel maken met een IDENTITY-kolom. Met Oracle 12c kunt u nu hetzelfde doen. Dit zou degenen moeten helpen die de overstap maken van SQL Server naar Oracle. Het stelt een bedrijf ook in staat om gemakkelijker een applicatie van SQL Server, of een andere database die de IDENTITY-kolom toelaat, naar Oracle te porten.

Eerst zal ik een tabel maken met de IDENTITY-kolom en deze vullen met enkele rijen gegevens.

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.
 

Merk op dat ik geen waarden in de ID-kolom heb ingevoegd. Laten we nu de tabel doorzoeken.

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

Zoals je kunt zien, zijn mijn ID-waarden toegevoegd zoals je zou verwachten. Bij het maken van mijn tabellen heb ik deze IDENTITY-kolom gedefinieerd met:    GENERATED BY DEFAULT ON NULL

De BY DEFAULT-clausule betekent dat Oracle automatisch de volgende waarde in de reeks toewijst als u deze weglaat in uw INSERT-instructie. Als u het opneemt, gebruikt Oracle uw opgegeven waarde. Overweeg dit:

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
 

Zoals je kunt zien, omdat ik expliciet ID=4 heb vermeld en Oracle die waarde heeft laten passeren. Wat gebeurt er als ik de volgende waarde probeer in te voeren, die 3 moet zijn?

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
Bovenstaande werkte zoals ik had verwacht. De eerstvolgende beschikbare ID-waarde is gebruikt. Maar zal de volgende invoeging '4' of '5' gebruiken?
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
Oh Oh! De dubbele waarde was toegestaan. Ik had verwacht dat er een Primary Key-beperking zou worden gecreëerd om het concept van een 'identiteitswaarde' af te dwingen, maar dat gebeurt niet. Welke beperkingen zijn er?
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
Dus de enige beperking is een NOT NULL-controlebeperking. Laten we nu die laatste rij verwijderen en een PK-beperking toevoegen.
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.
Nu zal ik ervoor zorgen dat ik wat gegevens heb om mee te testen.
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.
Dus ik heb expliciet ID=6 toegevoegd. Als dit is zoals toen ik expliciet ID=4 toevoegde, zal mijn volgende invoeging proberen om ID=6 te gebruiken en met de PK-beperking op zijn plaats, zal een uitzondering worden gegenereerd.
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
Dus de moraal van het verhaal is dat als je STANDAARD gebruikt, je voorbereid moet zijn op botsingen met identiteitswaarden. De standaardwaarde is ALTIJD in plaats van STANDAARD. Met ALTIJD zal Oracle altijd de volgnummergenerator gebruiken. Als u een id-waarde probeert op te geven, treedt er een uitzondering op.
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
De weergave *_TAB_COLUMNS kan u laten zien welke kolommen in een tabel IDENTITY-kolommen zijn.
SQL> select column_name,identity_column from user_tab_columns where table_name='TEST_TAB';
COLUMN_NAME     IDE
--------------- ---
ID              YES
VAL             NO
Als u de IDENTITY-kolom in uw tabellen gebruikt, moet u zorgvuldig testen om ervoor te zorgen dat u begrijpt dat deze correct werkt voor uw toepassing. Ik was verrast dat een PK- of UNIEKE-beperking niet automatisch werd opgenomen, waardoor ik een dubbele waarde kon toevoegen.
  1. Hoe u een lijst met ingeschakelde / uitgeschakelde controlebeperkingen in SQL Server-database kunt krijgen - SQL Server / TSQL-zelfstudie, deel 86

  2. Node.js en Microsoft SQL Server

  3. Hoe maak je een externe sleutel in Oracle SQL Developer?

  4. Oracle PL/SQL Bulk Collect met uitzonderingen opslaan Voorbeeld