2010-10-12 7 views

risposta

11
SELECT SCOPE_IDENTITY() 

Utilizzare questo dopo la sua dichiarazione di inserimento e lo restituirà l'identità inserita nel campo di applicazione. È possibile assegnare questo alla variabile o restituirlo in un parametro di output.

+0

Che cos'è un ambito? 2 thread sono ambiti diversi? –

+0

sì, lo sono. controllare http://msdn.microsoft.com/en-us/library/ms190315.aspx per la documentazione dettagliata di SCOPE_IDENTITY – Numenor

+0

in che modo SCOPE_IDENTITY() è diverso da @@ identity, SCOPE_IDENTITY() restituisce @@ identity ... e in la mia risposta, ho restituito l'identità @@ dopo l'inserimento ... – RameshVel

0

Penso che si possa scrivere un processo memorizzato che ha un parametro in/out e quindi prendere il valore dal parametro.

2

Prova questa

@@identity 

sotto il codice di esempio

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT @@Identity" 
SQLCommand.CommandText = strSQL 
Id = SQLCommand.ExecuteScalar() 
+0

Questo non sarà thread-safe. – Numenor

+0

@Numenor, come questo non è thread sicuro ... ?? – RameshVel

+0

@Numenor - di cosa stai parlando?Questo è perfettamente thread-safe, dal momento che entrambi i comandi vengono eseguiti in una singola query. –

3

Per questo scenario è necessario utilizzare Scope_Identity(). Ciò restituirà l'identità per l'ambito corrente. @@Identity restituisce l'ultima identità inserita.

Date un'occhiata a Scope Identity on MSDN - ci sono esempi di come si @@Identity restituire i valori errati rispetto all'utilizzo Scope_Identity

2

Un metodo di attuazione alternativa è quella di utilizzare la clausola OUTPUT del linguaggio T-SQL.

Ad esempio:

create table #tmpTable 
(
    ID int identity(1,1) not null primary key, 
    SomeValue varchar(20) not null 
); 

insert #tmpTable 
output INSERTED.ID 
values('SomeTextData') 

drop table #tmpTable; 

Da una prospettiva globale soluzione progettuale Auspico, pertanto, che si guarda per avvolgere la logica di inserimento in una stored procedure (restituendo il ID record inserito) che si chiama dal codice sorgente dell'applicazione .

0

Sono quasi sicuro che vorrete usare il metodo ObjectContext.ExecuteStoreQuery se avete bisogno del valore dell'identità, piuttosto che dello ObjectContext.ExecuteStoreCommand.

Avrete bisogno di usare, come altri hanno detto SCOPE_IDENTITY(), piuttosto che come @@IDENTITYSCOPE_IDENTITY() restituisce il valore di identità per l'ambito di esecuzione currente wheras @@IDENTITY "è una funzione di sistema che restituisce il valore ultimo inserito identità".

Qualcosa del genere dovrebbe fare il trucco:

using(var context = GetAContextThatsReadyToUse()) 
{ 
    var valueForColumn1 = 5; 
    var result = ExecuteStoreQuery<int>("INSERT INTO table1 (Column1) VALUES ({0});SELECT SCOPE_IDENTITY()", valueForColumn1); 

    foreach(var item in result) 
    { 
     // Should only return one result, which is the identity value inserted by ExecuteStoreQuery 
     Console.WriteLine(item); 
    } 
} 
0

ho avuto molte situazioni in cui qualcosa come 100 processi scrivesse a un tavolo alla volta. Non ho usato SCOPE_IDENTITY(), ma stavo avvolgendo l'intero insert/ID fetch in una transazione, e non c'era alcun problema con questo approccio.