2010-10-13 13 views
5

È possibile ottenere nuovi valori per Id (IDENTITY) prima di inserire dati in una tabella?È possibile ottenere nuovi valori per Id (IDENTITY) prima di inserire dati in una tabella?

Is è possibile scrivere qualcosa di simile:

INSERT INTO Table1 
SELECT *GET_NEW_IDENTITY*, Field1, Field2 FROM Table2 

Ho bisogno dei valori di Id perché voglio inserire i dati in Tabella 1 e, subito dopo, i dati di inserimento in un'altra tabella che ha una chiave esterna collegato a Table1 (con Id)

risposta

6

IDENT_CURRENT. Restituisce l'ultimo valore di identità generato per una tabella o vista specificata. L'ultimo valore di identità generato può essere per qualsiasi sessione e qualsiasi ambito.

SCOPE_IDENTITY. Restituisce l'ultimo valore identitario inserito in una colonna Identity nello stesso ambito. Un ambito è un modulo: una stored procedure, trigger, funzione o batch.

OUTPUT. Restituisce informazioni da, o espressioni basate su, ciascuna riga interessata da un'istruzione INSERT, UPDATE, DELETE o MERGE. [...] La clausola OUTPUT può essere utile per recuperare il valore dell'identità o delle colonne calcolate dopo un'operazione INSERT o UPDATE.

+2

Mai e poi mai usare ident_current per questo, NON restituirà il risultato corretto se hai più utenti! L'output è la scelta migliore o scope_identity() se la tua versione non supporta la clausola output. – HLGEM

0

No, perché è l'atto di aggiungere una riga che crea il nuovo valore di identità.

Per fare quello che vuoi,

SELECT newid = @@identity FROM table 

subito dopo l'INSERT

+0

@@ identità è molto pericoloso utilizzare e non restituirà in modo affidabile i risultati corretti. Non lo usi per questo scopo. – HLGEM

0

Perché si necessario per ottenere il valore di identità prima di fare l'inserto? Basta inserire l'inserto in Table2 restituendo SCOPE_IDENTITY() e quindi utilizzare il valore Id risultante per l'inserimento in Table1.

+0

Perché voglio fare un inserimento batch (non inserire riga per riga) per perf. –

+1

In tal caso, no, non puoi farlo. Devi ottenere l'identità dopo ogni inserimento di riga, come indicato da @smirkingman nella sua risposta. –

+0

@AJ: Ok, grazie –

2

è inoltre possibile che l'istruzione di inserimento restituisca il valore appena inserito per un utilizzo successivo. per esempio

create table demo(Id int identity primary key, data varchar(10)) 
go 
insert into demo(data) output inserted.Id values('something') 
0

Questa è solo una demo veloce. È possibile utilizzare un nuovo ID per l'inserimento per l'aggiornamento, inserire in un'altra tabella, query, ecc. In un altro modo. Sperando non mi inserisco errori nello script durante la formattazione, modifica di post

-- run [1] before this script once to have environment 

--create temporary table once if not dropped after 
-- really only ID field is needed, the others are for illustration 
create table #temp_id (Id int, d1 int, d2 int) 

select * from Table2;-- this is read-only, filled once here source 
select * from Table1;--interesting for following runs 

insert into Table1 
    OUTPUT INSERTED.id 
    -- really only ID is needed, the rest is for illustration 
    , inserted.d1, inserted.d2 INTO #temp_id 
select field1, field2, null-- null to be merged later 
-- or inserted/updated into another table 
    from Table2; 

select * from Table1; 
select * from #temp_id; 


MERGE Table1 AS TARGET 
    USING #temp_id AS SOURCE 
     ON (TARGET.id = SOURCE.id) 
    WHEN MATCHED 
--AND OR are redundant if Table1.ID is PK  
    THEN 
    UPDATE SET TARGET.IDnew = SOURCE.id; 


select * from Table1; 


--drop table #temp_id 
--drop table table1 
--drop table table2 

[1]
La riproduzione tabelle da domanda e riempire con i dati

create table Table1(Id int identity primary key, d1 int, d2 int, IDnew int) 
create table Table2(field1 int, field2 int) 
insert into table2 values(111,222) 
insert into table2 values(333,444) 
Problemi correlati