2010-03-05 6 views
15

Dopo aver eseguito un inserimento, seleziono SCOPE_IDENTITY o @@IDENTITY.In che modo SCOPE_IDENTITY restituisce null quando @@ IDENTITY non lo fa?

SCOPE_IDENTITY restituisce null ma @@IDENTITY no.

Non capisco come sia possibile.

Riesci a pensare a un motivo per cui ciò accade?

+3

Potete fornire ulteriori dettagli ... ad es. mostra il codice in cui viene chiamato SCOPE_IDENTITY() e spiega qualsiasi altra variabile (ad es. c'è un trigger coinvolto?). –

risposta

1

Ho trovato questo su MSDN: funzione

Lo SCOPE_IDENTITY() restituisce il valore null se la funzione viene richiamata prima di qualsiasi istruzioni INSERT in una colonna identità avvenire nell'ambito.

potete leggere qui: http://msdn.microsoft.com/en-us/library/ms190315.aspx

Il codice SQL sarebbe molto utile.

15

ecco un esempio di come SCOPE_IDENTITY() sarà nullo, ma @@ IDENTITY avrà un valore:

inserimento in una tabella senza identità, tale tabella ha un trigger di inserimento che poi inserti in una tabella cronologia con un'identità. SCOPE_IDENTITY() sarà null (nessuna identità nell'ambito locale), ma @@ IDENTITY riporterà l'identità dal trigger.

A proposito, c'è un bug noto con SCOPE_IDENTITY(): https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

La cosa migliore con le identità è quella di utilizzare OUTPUT INTO, è in grado di catturare una serie di ID e non è soggetto alla SCOPE_IDENTITY() bug:

declare @x table (tableID int identity not null primary key, datavalue varchar(10)) 
declare @y table (tableID int, datavalue varchar(10)) 

INSERT INTO @x values ('aaaa') 
INSERT INTO @x values ('bbbb') 
INSERT INTO @x values ('cccc') 
INSERT INTO @x values ('dddd') 
INSERT INTO @x values ('eeee') 


INSERT INTO @x 
    (datavalue) 
    OUTPUT INSERTED.tableID, INSERTED.datavalue  --<<<<OUTPUT INTO SYNTAX 
    INTO @y           --<<<<OUTPUT INTO SYNTAX 
SELECT 
    'value='+CONVERT(varchar(5),dt.NewValue) 
    FROM (SELECT id as NewValue from sysobjects where id<20) dt 
    ORDER BY dt.NewValue 


select * from @x 
select * from @y 
+0

Sebbene sia vero, non penso sia necessario entrare in questi dettagli su un bug oscuro che si manifesta solo quando si inseriscono più righe e si tenta di recuperare una singola identità. 'SCOPE_IDENTITY()' funziona senza problemi nel 99% dei casi.Di nuovo, questo è tutto corretto ma per qualcuno che sta ancora imparando la differenza tra '@@ IDENTITY' e' SCOPE_IDENTITY() 'potrebbe essere un po 'schiacciante. – Aaronaught

+2

@Aaronaught, l'OP non fornisce il codice INSERT, potrebbe essere un INSERT-SELECT che utilizza il parallelismo. Perché scommetto che c'è una probabilità dell'1%! ;-) Almeno nella mia risposta presenterò due modi diversi in cui @@ Identity e SCOPE_IDENTITY() possono avere valori diversi, e non solo le loro definizioni BOL. –

11

KM ha colpito il chiodo sulla testa:

  • @@IDENTITY fornisce l'ultimo valore IDENTITY inserito, indipendentemente dalla posizione in cui è stata inserita la tabella (si pensi ai trigger , ad es. nelle tabelle di controllo! O anche una cascata di trigger .....)

  • SCOPE_IDENTITY() ti dà l'ultimo IDENTITY inserito nell'ambito della sua dichiarazione, per esempio sul tavolo (s) che il proprio, dichiarazione reale riferimento (non quelli che potrebbero essere stati toccati da un trigger)

+1

SCOPE_IDENTITY() non restituisce risultati corretti quando viene utilizzato il parallelismo: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811 –

+1

Mi piace questa risposta migliore, specifica e pertinente. – Aaronaught

+0

come risponde questa risposta alla domanda? Qual è la soluzione per mantenere scope_identity IN scope? questo è il vero secondo problema al suo problema. – PositiveGuy

5

SCOPE_IDENTITY tornerà anche NULL quando l'inserto è di sp_executesql come non si è più in sei portata dell'INSERTO!

Problemi correlati