Ich lebe und arbeite in der Nähe einer Microsoft-Einrichtung. Daher sind viele unserer derzeitigen Mitarbeiter ehemalige Microsoft-Mitarbeiter, die einen SQL Server-Hintergrund haben. Mit SQL Server können Sie eine Tabelle mit einer IDENTITY-Spalte erstellen. Mit Oracle 12c können Sie jetzt dasselbe tun. Dies sollte denjenigen helfen, die den Übergang von SQL Server zu Oracle vornehmen. Es ermöglicht einem Unternehmen auch eine einfachere Portierung einer Anwendung von SQL Server oder jeder anderen Datenbank, die die IDENTITY-Spalte zulässt, zu Oracle.
Zuerst erstelle ich eine Tabelle mit der IDENTITY-Spalte und fülle sie mit einigen Datenzeilen.
SQL> Tabelle test_tab erstellen (2 id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY, 3 val VARCHAR2(20));Tabelle erstellt.SQL> insert into test_tab (val) values ('my first row');1 row erstellt.SQL> einfügen in test_tab (val) Werte ('meine zweite Zeile');1 Zeile erstellt.SQL> commit;Commit abgeschlossen.
Beachten Sie, dass ich keine Werte in die ID-Spalte eingefügt habe. Lassen Sie uns nun die Tabelle abfragen.
SQL> select * from test_tab;ID VAL---------- --------------------1 meine erste Zeile2 meine zweite Zeile
Wie Sie sehen können, wurden meine ID-Werte wie erwartet hinzugefügt. Bei meiner Tabellenerstellung habe ich diese IDENTITY-Spalte definiert mit: GENERATED BY DEFAULT ON NULL
Die BY DEFAULT-Klausel bedeutet, dass Oracle automatisch den nächsten Wert in der Sequenz zuweist, wenn Sie ihn in Ihrer INSERT-Anweisung weglassen. Wenn Sie es einschließen, verwendet Oracle Ihren angegebenen Wert. Bedenken Sie Folgendes:
SQL> in test_tab Werte einfügen (4,'angegebene ID=4');1 Zeile erstellt.SQL> commit;commit abgeschlossen.SQL> select * from test_tab; ID VAL---------- -------------------- 1 meine erste Zeile 2 meine zweite Zeile 4 angegebene ID=4
Wie Sie sehen können, weil ich ID=4 explizit angegeben habe und Oracle diesen Wert passieren lässt. Was passiert, wenn ich versuche, den nächsten Wert einzufügen, der 3 sein sollte?
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 meine erste Zeile 2 meine zweite Zeile 4 angegebene ID=4 3 meine Zeile nach ID =4Das obige funktionierte wie ich erwartet hatte. Der nächste verfügbare ID-Wert wurde verwendet. Aber wird die nächste Einfügung '4' oder '5' verwenden?
SQL> insert into test_tab (val) values ('my five row');1 row created.SQL> commit;Commit complete.SQL> select * from test_tab; ID VAL---------- -------------------- 1 meine erste Zeile 2 meine zweite Zeile 4 angegebene ID=4 3 meine Zeile nach ID =4 4 meine fünfte ReiheOh-oh! Der doppelte Wert wurde zugelassen. Ich hätte erwartet, dass eine Primärschlüsseleinschränkung erstellt wird, um das Konzept eines „Identitäts“-Werts durchzusetzen, aber das passiert nicht. Welche Beschränkungen gibt es?
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" IST NICHT NULLDie einzige Einschränkung ist also eine NOT NULL-Check-Einschränkung. Jetzt entfernen wir diese letzte Zeile und fügen eine PK-Einschränkung hinzu.
SQL> delete from test_tab where val='meine fünfte Zeile';1 Zeile gelöscht.SQL> commit;Commit complete.SQL> alter table test_tab add constraint test_tab_pk primary key (id);Tabelle geändert.Jetzt werde ich sicherstellen, dass ich einige Daten zum Testen habe. 6,'explizit gesetzte ID=6');1 Zeile erstellt.SQL> commit;Commit abgeschlossen.SQL> select * from test_tab; ID VAL---------- -------------------- 1 meine erste Zeile 2 meine zweite Zeile 4 angegebene ID=4 3 meine Zeile nach ID =4 5 nach pk-Einschränkung 6 explizit festgelegte ID =66 ausgewählte Zeilen. Also habe ich explizit ID=6 hinzugefügt. Wenn dies der Fall ist, als ich explizit ID=4 hinzugefügt habe, versucht meine nächste Einfügung, ID=6 zu verwenden, und mit der PK-Einschränkung wird eine Ausnahme ausgelöst.
SQL> insert into test_tab (val) values (' after ID=6');insert in test_tab (val) values ('after ID=6')*ERROR at line 1:ORA-00001:Unique Constraint (PEASLAND.TEST_TAB_PK) verletztDie Moral der Geschichte lautet also, wenn Sie ON DEFAULT verwenden, seien Sie darauf vorbereitet, mit Identitätswertkollisionen umzugehen. Der Standardwert ist IMMER statt EIN DEFAULT. Bei ALWAYS verwendet Oracle immer den Sequenznummerngenerator. Wenn Sie versuchen, einen id-Wert anzugeben, tritt eine Ausnahme auf.
SQL> create table test_tab2(id-Nummer wird immer als Identität generiert, val varchar2(20));Table created.SQL> insert into test_tab2(id,val) Werte (1, 'erste Zeile'); einfügen in test_tab2(id, val) Werte (1, 'erste Zeile') *FEHLER in Zeile 1:ORA-32795:Einfügen in eine generierte Always-Identity-Spalte nicht möglichDie Ansicht *_TAB_COLUMNS kann Ihnen zeigen, welche Spalten in einer Tabelle IDENTITY-Spalten sind.
SQL> select column_name,identity_column from user_tab_columns where table_name='TEST_TAB';COLUMN_NAME IDE-------------- - ---ID YESVAL NEINWenn Sie die IDENTITY-Spalte in Ihren Tabellen verwenden, achten Sie beim Testen darauf, dass Sie verstehen, dass sie für Ihre Anwendung richtig funktioniert. Ich war überrascht, dass eine PK- oder UNIQUE-Einschränkung nicht automatisch enthalten war, wodurch ich einen doppelten Wert hinzufügen konnte.