Która z nich jest najlepszą opcją uzyskania wartości tożsamości, którą właśnie wygenerowałem przez wstawkę? Jaki jest wpływ tych stwierdzeń na wydajność?
SCOPE_IDENTITY()
- Funkcja agregująca
MAX()
- WYBIERZ
TOP 1
IdentityColumn FROM TableNameORDER BY IdentityColumn DESC
Odpowiedzi:
Użyj,
SCOPE_IDENTITY()
jeśli wstawiasz pojedynczy wiersz i chcesz odzyskać wygenerowany identyfikator.Wynik:
Użyj
OUTPUT
klauzuli, jeśli wstawiasz wiele wierszy i potrzebujesz pobrać zestaw wygenerowanych identyfikatorów.Wynik:
Pomijając wydajność, są to jedyne, które z pewnością są poprawne na domyślnym poziomie izolacji i / lub z wieloma użytkownikami. Nawet jeśli zignorujesz aspekt poprawności, SQL Server przechowuje wstawioną wartość w
SCOPE_IDENTITY()
pamięci, więc naturalnie będzie to szybsze niż uruchomienie i uruchomienie własnego izolowanego zapytania względem tabeli lub tabel systemowych.Ignorowanie aspektu poprawności jest jak mówienie listonoszowi, że wykonał dobrą robotę dostarczając dzisiejszą pocztę - zakończył swoją trasę o 10 minut szybciej niż przeciętny czas, problem polega na tym, że żadna poczta nie została dostarczona do właściwego domu.
Nie używaj żadnego z poniższych:
@@IDENTITY
- ponieważ nie można tego użyć we wszystkich scenariuszach, na przykład gdy tabela z kolumną tożsamości ma wyzwalacz, który wstawia również do innej tabeli z własną kolumną tożsamości - odzyskasz niewłaściwą wartość.IDENT_CURRENT()
- Wchodzę tutaj szczegółowo w to , a komentarze są również przydatne do czytania, ale zasadniczo, w przypadku współbieżności, często otrzymasz błędną odpowiedź.MAX()
lubTOP 1
- musisz zabezpieczyć te dwa oświadczenia za pomocą szeregowalnej izolacji, aby mieć pewność, żeMAX()
nie dostaniesz się od kogoś innego. Jest to o wiele droższe niż zwykłe używanieSCOPE_IDENTITY()
.Te funkcje również zawodzą, gdy wstawisz dwa lub więcej wierszy i potrzebujesz wygenerować wszystkie wartości tożsamości - twoją jedyną opcją jest
OUTPUT
klauzula.źródło
Oprócz wydajności wszystkie mają raczej różne znaczenia.
SCOPE_IDENTITY()
poda ostatnią wartość tożsamości wstawioną do dowolnej tabeli bezpośrednio w bieżącym zakresie (zakres = partia, procedura składowana itp., ale nie w ramach, powiedzmy, wyzwalacza uruchomionego przez bieżący zakres).IDENT_CURRENT()
poda ostatnią wartość tożsamości wstawioną do określonej tabeli z dowolnego zakresu przez dowolnego użytkownika.@@IDENTITY
daje ostatnią wartość tożsamości wygenerowaną przez najnowszą instrukcję INSERT dla bieżącego połączenia, niezależnie od tabeli lub zakresu. (Uwaga dodatkowa: Access korzysta z tej funkcji, a zatem ma pewne problemy z wyzwalaczami, które wstawiają wartości do tabel z kolumnami tożsamości).Użycie
MAX()
lubTOP 1
może dać całkowicie błędne wyniki, jeśli tabela ma negatywny krok identyczności lub w wierszu wstawiono wierszeSET IDENTITY_INSERT
. Oto skrypt demonstrujący wszystkie te:Podsumowanie: kij z
SCOPE_IDENTITY()
,IDENT_CURRENT()
lub@@IDENTITY
, i upewnij się, że używasz ten, który powraca co rzeczywiście potrzebne.źródło
IDENT_CURRENT()
i@@IDENTITY
kiedy pokazuje on, że wyniki są niepoprawne?IDENT_CURRENT()
zwraca. MAX () nigdy nie zwraca poprawnej wartości poza pierwszy wiersz, ponieważ id odlicza wstecz, a przyIDENTITY_INSERT
on, 9005 nie jest wygenerowaną wartością tożsamości, dlatego nie jest odzwierciedlona przezIDENT_CURRENT()
. Ale może zwracać „niepoprawne” wyniki, jeśli naprawdę chcesz uzyskaćSCOPE_IDENTITY()
zwrot. Wybierz odpowiednie narzędzie do pracy.@@IDENTITY
prawie nigdy nie jest to idealny sposób na uzyskanie wygenerowanych wartości tożsamości. Głównym punktem jest to, żeMAX()
alboTOP 1
są jakby mniej wiarygodne wersjiIDENT_CURRENT()
, która jest perfekcyjnie funkcja do użycia jeśli rozumiesz, co robi. Może być przydatny do prac konserwacyjnych lub czegoś takiego.