2016-01-15 16 views
8

Poiché Oracle 12c è possibile utilizzare i campi IDENTITY.Recupera Oracle ultimo IDENTITY inserito

C'è un modo per recuperare l'ultima identità inserita (ad esempio select @@identity o select LAST_INSERTED_ID() e così via)?

+0

Le colonne 'identity' usano ancora una sequenza in background. Dovresti essere in grado di usare il solito 'sequence.currval' per ottenere l'ultimo valore generato. –

+0

Il problema è che devo conoscere il nome della sequenza. Actaully è difficile sapere il nome della tabella e il nome dello schema in cui ho inserito i record (il nome della sequenza è correlato a loro). – bubi

+1

Come si può _non_ conoscere il nome della tabella in cui si sta inserendo? –

risposta

7

Bene. Oracle utilizza sequenze e valori predefiniti per la funzionalità IDENTITY in 12c. Quindi è necessario conoscere le sequenze per la tua domanda.

Prima creare una tabella di identità di test.

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

Innanzitutto, consente di trovare il nome della sequenza che viene creato con questa colonna Identity. Questo nome di sequenza è un valore predefinito nella tabella.

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

per me questo valore è "ISEQ $$ _ 193606"

inserire alcuni valori.

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

quindi inserire il valore e trovare l'identità.

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

dovresti vedere il tuo valore di identità. Se si desidera fare in un blocco utilizzare

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

L'ultimo ID è il nome della colonna della mia identità.

+0

Questa è l'unica risposta corretta. Devi solo assicurarti di valutare ' .currval' nella stessa sessione in cui stai inserendo. – Ben

0

Qual è il tuo ambito, globale o ultimo utente inserito? Se globale basta usare

SELECT mytable_seq.nextval MyTableID FROM DUAL 

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

Se incapsulare specifico tuoi inserti & di query all'interno di una transazione.

+0

Grazie per la risposta! L'ambito è l'ultimo utente. Penso che il tuo suggerimento funzioni solo per MySQL. In Oracle non funziona (errore di sintassi) aggiungendo anche la clausola 'FROM Dual'. – bubi

+0

oh scusa, ho aggiornato il collegamento –

+0

Questo è per globale (potrei anche usare corrente ma è ancora globale) – bubi

1

IDENTITY colonna utilizza un SEQUENCE "under the hood" - creazione e rilascio della sequenza automaticamente con la tabella che utilizza. Inoltre, è possibile specificare start e incrementare i parametri utilizzando , avviare con 1000 e incrementare di 2. È davvero molto conveniente utilizzare IDENTITY quando non si desidera utilizzare direttamente i valori.

Ma se è necessario in qualche modo utilizzare direttamente la sequenza, è necessario utilizzare un'altra opzione disponibile in Oracle 12c: valori di colonna predefiniti. I valori predefiniti di fabbrica possono essere generati dalla sequenza nextval o currval. Per consentire di avere un nome di sequenza comprensibile e usarlo come "identità" senza un trigger.

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

Sarà sempre possibile chiamare: my_new_table_seq.currval.

È possibile ottenere l'ID generato da SEQUENCE nell'istruzione di inserimento utilizzando la clausola RETURNING.

Ad esempio, creare una tabella temporanea:

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

fare qualche inserto di risparmio di questo valore nella tabella temporanea:

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; 

Ora avete "locale" id inserito.

select "id" from local_identity_storage 
1

Sembra che Oracle abbia implementato IDENTITY solo per dire che supportano le identità. Tutto è ancora implementato utilizzando SEQUENCES e talvolta è necessario accedere allo SEQUENCE per eseguire alcuni dei lavori (ad esempio, recuperare l'ultimo inserito IDENTITY).

Non c'è un modo per recuperare il IDENTITY simile a MySQL, SQL Server, DB2 e così via, è necessario recuperarlo utilizzando lo SEQUENCE.

+1

Sì, è un'astrazione su SEQUENCE, ma cambierà la sintassi della clausola INSERT e questa modifica sarà anche si riflettono nelle prestazioni. Guarda questo test (inserendo in Oracle 12c) usando tre diverse tecniche (i risultati sono stati estratti da qui [https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1]): 1) TRIGGER_IDENTITY : Time = 217 hsecs CPU Time = 204 hsecs; 2) SEQUENZA DI UTILIZZO DIRETTO: Tempo = 26 hsecs Tempo CPU = 22 hsecs; 3) REAL_IDENTITY: Tempo = 28 hsecs CPU Time = 26 hsecs. –

+0

È stato fatto per facilitare le migrazioni al database Oracle. Non è necessario creare manualmente sequenze e trigger per attivarli sugli inserti, il database lo fa ora per te. Non parlo per Oracle, ma ho un white paper sull'argomento se sei interessato a cos'altro abbiamo fatto in 12c per aiutare con le migrazioni. – thatjeffsmith

+0

@thatjeffsmith Sto esattamente facendo una migrazione ma senza un comportamento simile ad altri DBMS il lavoro è difficile. – bubi

0

prega di controllare

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

Essa vi aiuterà a recuperare l'ultima riga inserita

Problemi correlati