Domanda

Qual è il modo migliore per ottenere IDENTITY della riga inserita?

Lo so @@IDENTITY E IDENT_CURRENT E SCOPE_IDENTITY ma non capisco i pro e i contro di ciascuno.

Qualcuno può spiegare le differenze e quando dovrei usarli?

È stato utile?

Soluzione

  • @@IDENTITY restituisce l'ultimo valore di identità generato per qualsiasi tabella nella sessione corrente, in tutti gli ambiti. Devi stare attento qui, poiché è trasversale.Potresti ottenere un valore da un trigger, anziché dalla tua dichiarazione corrente.

  • SCOPE_IDENTITY() restituisce l'ultimo valore di identità generato per qualsiasi tabella nella sessione corrente e nell'ambito corrente. Generalmente quello che vuoi usare.

  • IDENT_CURRENT('tableName') restituisce l'ultimo valore di identità generato per una tabella specifica in qualsiasi sessione e in qualsiasi ambito.Ciò ti consente di specificare da quale tabella desideri il valore, nel caso in cui le due sopra non siano esattamente ciò di cui hai bisogno (molto rara).Inoltre, come @Guy Starbuck menzionato, "Potresti usarlo se vuoi ottenere il valore IDENTITY corrente per una tabella in cui non hai inserito un record."

  • IL OUTPUT clausola del INSERT ti consentirà di accedere a ogni riga inserita tramite tale istruzione.Poiché ha come ambito l'istruzione specifica, lo è più semplice rispetto alle altre funzioni sopra.Tuttavia, è un po' più prolisso (dovrai inserire in una tabella una variabile/tabella temporanea e quindi interrogarla) e fornisce risultati anche in uno scenario di errore in cui viene eseguito il rollback dell'istruzione.Detto questo, se la tua query utilizza un piano di esecuzione parallela, questo è il file unico metodo garantito per ottenere l'identità (a meno di disattivare il parallelismo).Tuttavia, viene eseguito Prima trigger e non può essere utilizzato per restituire valori generati dal trigger.

Altri suggerimenti

Credo che il metodo più sicuro e accurato per recuperare l'ID inserito sarebbe utilizzare la clausola di output.

ad esempio (tratto dal seguente MSDN articolo)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

Sto dicendo la stessa cosa degli altri ragazzi, quindi hanno tutti ragione, sto solo cercando di renderlo più chiaro.

@@IDENTITY restituisce l'id dell'ultima cosa che è stata inserita dalla connessione del tuo cliente al database.
Nella maggior parte dei casi funziona bene, ma a volte un trigger inserisce una nuova riga di cui non sei a conoscenza e otterrai l'ID da questa nuova riga, invece di quella che desideri

SCOPE_IDENTITY() risolve questo problema.Restituisce l'id dell'ultima cosa che hai inserito nel codice SQL tu hai inviato alla banca dati.Se i trigger creano righe aggiuntive, non verranno restituiti il ​​valore sbagliato.Evviva

IDENT_CURRENT restituisce l'ultimo ID inserito da chiunque.Se qualche altra app inserisce un'altra riga in un momento sfortunato, otterrai l'ID di quella riga invece del tuo.

Se vuoi andare sul sicuro, usalo sempre SCOPE_IDENTITY().Se rimani fedele @@IDENTITY e qualcuno decide di aggiungere un trigger in seguito, tutto il tuo codice si romperà.

Il migliore (leggi:il modo più sicuro) per ottenere l'identità di una riga appena inserita è utilizzare il metodo output clausola:

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

Aggiungere

SELECT CAST(scope_identity() AS int);

alla fine dell'istruzione insert sql, quindi

NewId = command.ExecuteScalar()

lo recupererò.

MSDN

@@IDENTITY, SCOPE_IDENTITY e IDENT_CURRENT sono funzioni simili in quanto restituiscono l'ultimo valore inserito nella colonna IDENTITY di una tabella.

@@IDENTITY e SCOPE_IDENTITY restituiranno l'ultimo valore di identità generato in qualsiasi tabella nella sessione corrente.Tuttavia, SCOPE_IDENTITY restituisce il valore solo nell'ambito corrente;@@IDENTITY non è limitato a un ambito specifico.

IDENT_CURRENT non è limitato dall'ambito e dalla sessione;è limitato a una tabella specificata.IDENT_CURRENT restituisce il valore identità generato per una tabella specifica in qualsiasi sessione e qualsiasi ambito.Per ulteriori informazioni, vedere IDENT_CURRENT.

  • IDENT_CURRENT è una funzione che accetta una tabella come argomento.
  • @@IDENTITÀ potrebbe restituire risultati confusi quando è presente un trigger sul tavolo
  • SCOPE_IDENTITY è il tuo eroe per la maggior parte del tempo.

Quando si utilizza Entity Framework, utilizza internamente il file OUTPUT tecnica per restituire il valore ID appena inserito

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g 
   JOIN dbo.TurboEncabulators AS t 
   ON g.Id = t.TurboEncabulatorID 
WHERE @@ROWCOUNT > 0

I risultati di output vengono archiviati in una variabile di tabella temporanea, uniti nuovamente alla tabella e restituiscono il valore della riga fuori dalla tabella.

Nota:Non ho idea del motivo per cui EF dovrebbe unire internamente la tabella effimera alla tabella reale (in quali circostanze i due non corrisponderebbero).

Ma questo è ciò che fa EF.

Questa tecnica (OUTPUT) è disponibile solo in SQL Server 2008 o versioni successive.

@@IDENTITÀ è l'ultima identità inserita utilizzando la connessione SQL corrente.Questo è un buon valore da restituire da una procedura memorizzata di inserimento, in cui hai solo bisogno dell'identità inserita per il tuo nuovo record e non ti interessa se in seguito sono state aggiunte più righe.

SCOPE_IDENTITY è l'ultima identità inserita utilizzando la connessione SQL corrente e nell'ambito corrente, ovvero se fosse inserita una seconda IDENTITÀ in base a un trigger dopo l'inserimento, non si rifletterebbe in SCOPE_IDENTITY, ma solo nell'inserimento eseguito.Francamente, non ho mai avuto un motivo per usarlo.

IDENT_CURRENT(nometabella) è l'ultima identità inserita indipendentemente dalla connessione o dall'ambito.Puoi usarlo se vuoi ottenere il valore IDENTITY corrente per una tabella in cui non hai inserito un record.

Non posso parlare con altre versioni di SQL Server, ma nel 2012 l'output diretto funziona perfettamente.Non è necessario preoccuparsi di una tabella temporanea.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

A proposito, questa tecnica funziona anche quando si inseriscono più righe.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

Produzione

ID
2
3
4

SEMPRE usa scope_identity(), non c'è MAI bisogno di nient'altro.

Dopo la tua dichiarazione di inserimento devi aggiungere questo.E assicurati del nome della tabella in cui vengono inseriti i dati. Otterrai la riga corrente, nessuna riga dove, interessata proprio ora dall'istruzione di inserimento.

IDENT_CURRENT('tableName')

Se stai cercando l'ultimo ID aggiunto/aggiornato, potrebbe essere un po' vecchio stile, ma ci sono molte persone che utilizzano PHP più vecchio, precedente alla 5.5 per essere più precisi.Maggiori dettagli possono essere trovati su http://php.net/manual/en/function.mysql-insert-id.php

$last = mysql_insert_id();

Creare un uuid e inserirlo anche in una colonna.Quindi puoi facilmente identificare la tua riga con l'uuid.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top