2016-01-15 12 views
8

Seit Oracle 12c können wir IDENTITY Felder verwenden.Abrufen von Oracle zuletzt eingefügt IDENTITY

Gibt es eine Möglichkeit, die zuletzt eingefügte Identität (d. H. select @@identity oder select LAST_INSERTED_ID() usw.) abzurufen?

+0

Die 'identity' Spalten noch verwenden, um eine Sequenz im Hintergrund abgerufen werden kann. Sie sollten in der Lage sein, den üblichen 'sequence.currval' zu verwenden, um den letzten generierten Wert zu erhalten. –

+0

Das Problem ist, dass ich den Namen der Sequenz kennen muss. Actaully ist schwer den Namen der Tabelle und den Namen des Schemas zu kennen, in dem ich die Datensätze eingefügt habe (der Name der Sequenz ist mit ihnen verwandt). – bubi

+1

Wie können Sie den Namen der Tabelle, in die Sie einfügen, _nicht_ kennen? –

Antwort

7

Gut. Oracle verwendet Sequenzen und Standardwerte für die IDENTITY-Funktionalität in 12c. Daher müssen Sie über Sequenzen für Ihre Frage wissen.

Erstellen Sie zunächst eine Test-Identitätstabelle.

CREATE TABLE IDENTITY_TEST_TABLE 
(
    ID NUMBER GENERATED ALWAYS AS IDENTITY 
, NAME VARCHAR2(30 BYTE) 
); 

Zuerst suchen wir Ihren Sequenznamen, der mit dieser Identitätsspalte erstellt wird. Dieser Sequenzname ist ein Standardwert in Ihrer Tabelle.

Select TABLE_NAME, COLUMN_NAME, DATA_DEFAULT from USER_TAB_COLUMNS 
where TABLE_NAME = 'IDENTITY_TEST_TABLE'; 

für mich ist dieser Wert "ISEQ $$ _ 193.606"

einige Werte einfügen.

INSERT INTO IDENTITY_TEST_TABLE (name) VALUES ('atilla'); 
INSERT INTO IDENTITY_TEST_TABLE (name) VALUES ('aydın'); 

dann Wert einfügen und Identität finden.

INSERT INTO IDENTITY_TEST_TABLE (name) VALUES ('atilla'); 
SELECT "ISEQ$$_193606".currval from dual; 

sollten Sie Ihren Identitätswert sehen. Wenn Sie in einem Block arbeiten möchten, verwenden Sie

declare 
    s2 number; 
begin 
    INSERT INTO IDENTITY_TEST_TABLE (name) VALUES ('atilla') returning ID into s2; 
    dbms_output.put_line(s2); 
end; 

Letzte ID ist meine Identität Spaltenname.

+0

Dies ist die einzige richtige Antwort. Sie müssen nur sicherstellen, dass Sie ' .currval' in der gleichen Sitzung evaluieren, in die Sie einfügen. – Ben

0

Was ist Ihr Bereich, globaler oder letzter Benutzer eingefügt? Wenn nur global

SELECT mytable_seq.nextval MyTableID FROM DUAL 

https://www.sitepoint.com/community/t/oracle-last-insert-id-question/1402

Wenn bestimmte encapsulate Ihre Einsätze & Abfrage innerhalb einer Transaktion verwenden.

+0

Danke für die Antwort! Der Bereich ist der letzte Benutzer. Ich denke, dass Ihr Vorschlag nur für MySQL funktioniert. In Oracle funktioniert nicht (Syntaxfehler) auch "FROM Dual" -Klausel hinzufügen. – bubi

+0

oh sorry, ich habe den Link aktualisiert –

+0

Das ist für global (ich könnte auch verwenden, aber ist immer noch global) – bubi

1

IDENTITY Spalte verwendet eine SEQUENCE "unter der Haube" - Erstellen und Löschen von Sequenz automatisch mit der Tabelle, die es verwendet. Sie können auch angeben, mit Parametern beginnen und inkrementieren, indem Sie verwenden, beginnen Sie mit 1000 und erhöhen Sie um 2. Es ist wirklich sehr bequem, IDENTITY zu verwenden, wenn Sie seine Werte nicht direkt verwenden möchten. Wenn Sie die Sequenz direkt bedienen müssen, sollten Sie verwenden. Sutch Standard Werte konnten aus der Sequenz nextval oder currval generiert werden. Damit Sie einen verständlichen Sequenznamen haben und ihn ohne Trigger als "Identität" verwenden können.

create table my_new_table 
(id number default my_new_table_seq.nextval not null) 

Sie können immer anrufen: my_new_table_seq.currval.

Es ist möglich, ID von SEQUENCE auf Insert-Anweisung mit RETURNING Klausel generiert zu bekommen.

Erstellen Sie zum Beispiel eine temporäre Tabelle:

create global temporary table local_identity_storage ("id" number) on commit delete rows 

einige Einsatz Machen Sie diesen Wert in der temporären Tabelle zu speichern:

CREATE TABLE identity_test_table (
    id_ident   NUMBER GENERATED BY DEFAULT AS IDENTITY, 
    same_value VARCHAR2(100) 
); 

declare 
    v_id number(10, 0); 
begin 
    INSERT INTO identity_test_table 
    (same_value) 
    VALUES 
    ('Test value') 
    RETURNING id_ident INTO v_id; 

    insert into local_identity_storage ("id") values (v_id); 
    commit; 
end; 

Jetzt Sie "local" eingefügt ID haben.

select "id" from local_identity_storage 
1

Es scheint, dass Oracle IDENTITY implementiert, nur um zu sagen, dass sie Identitäten unterstützen. Alles wird noch implementiert mit SEQUENCES und manchmal müssen Sie auf die SEQUENCE zugreifen, um einige der Arbeit zu machen (d. H. Die neueste eingefügte IDENTITY abrufen).

Es gibt keine Möglichkeit, die IDENTITY ähnlich wie MySQL, SQL Server, DB2 usw. abzurufen. Sie müssen sie unter Verwendung der SEQUENCE abrufen.

+1

Ja, es ist Abstraktion über SEQUENCE, aber es wird die Syntax der INSERT-Klausel ändern und diese Änderung wird auch sich in der Leistung widerspiegeln. Sehen Sie sich diesen Test an (Einfügen in Oracle 12c), indem Sie drei verschiedene Techniken verwenden (die Ergebnisse stammen von hier [https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1]): 1) TRIGGER_IDENTITY : Zeit = 217 hsecs CPU Zeit = 204 hsecs; 2) DIREKTE GEBRAUCHSEQUENZ: Zeit = 26 hsecs CPU Zeit = 22 hsec; 3) REAL_IDENTITY: Zeit = 28 hsecs CPU Zeit = 26 hsecs. –

+0

Es wurde gemacht, um Migrationen auf Oracle Database einfacher zu machen. Sie müssen keine Sequenz und Trigger manuell erstellen, um sie auf Einfügungen auszulösen - die Datenbank erledigt dies für Sie. Ich spreche nicht für Oracle, aber ich habe ein Whitepaper zu diesem Thema, wenn Sie daran interessiert sind, was wir sonst in 12c getan haben, um Migrationen zu unterstützen. – thatjeffsmith

+0

@thatjeffsmith Ich mache gerade eine Migration, aber ohne ein ähnliches Verhalten wie bei anderen DBMS ist die Arbeit schwierig. – bubi

0

Bitte überprüfen

INSERT INTO yourtable (....) 
    VALUES (...) 
    RETURNING pk_id INTO yourtable; 

Es zuletzt eingefügte Zeile

Verwandte Themen