Jaki jest najlepszy sposób na uzyskanie IDENTITY
wstawionego wiersza?
Wiem o @@IDENTITY
i IDENT_CURRENT
a SCOPE_IDENTITY
, ale nie rozumiem, plusy i minusy przymocowane do siebie.
Czy ktoś może wyjaśnić różnice i kiedy powinienem ich używać?
sql
sql-server
tsql
Oded
źródło
źródło
INSERT INTO Table1(fields...) OUTPUT INSERTED.id VALUES (...)
lub starsza metoda:INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();
możesz pobrać w c # za pomocą ExecuteScalar ().OUTPUT
klauzulę w SQL Server.Odpowiedzi:
@@IDENTITY
zwraca ostatnią wartość tożsamości wygenerowaną dla dowolnej tabeli w bieżącej sesji we wszystkich zakresach. Musisz tu być ostrożny , ponieważ jest to w wielu zakresach. Możesz otrzymać wartość z wyzwalacza, zamiast z bieżącego wyciągu.SCOPE_IDENTITY()
zwraca ostatnią wartość tożsamości wygenerowaną dla dowolnej tabeli w bieżącej sesji i bieżący zakres. Ogólnie to, czego chcesz użyć .IDENT_CURRENT('tableName')
zwraca ostatnią wartość tożsamości wygenerowaną dla określonej tabeli w dowolnej sesji i dowolnym zakresie. Pozwala to określić, z której tabeli chcesz uzyskać wartość, na wypadek gdyby dwie powyższe nie były dokładnie tym, czego potrzebujesz ( bardzo rzadko ). Ponadto, jak wspomniał @ Guy Starbuck , „Możesz użyć tego, jeśli chcesz uzyskać bieżącą wartość TOŻSAMOŚCI dla tabeli, do której nie wstawiłeś rekordu”.OUTPUT
Klauzula zINSERT
oświadczeniem pozwoli Ci uzyskać dostęp do każdego wiersza, który został wstawiony za pośrednictwem tego rachunku. Ponieważ zakres obejmuje określoną instrukcję, jest prostszy niż w przypadku innych powyższych funkcji. Jest to jednak trochę bardziej szczegółowe (musisz wstawić do tabeli zmienna / temp tabela, a następnie zapytać o to) i daje wyniki nawet w scenariuszu błędu, w którym instrukcja jest wycofywana. To powiedziawszy, jeśli twoje zapytanie korzysta z równoległego planu wykonania, jest to jedyna gwarantowana metoda uzyskania tożsamości (bez wyłączania równoległości). Jest on jednak wykonywany przed wyzwalaczami i nie można go użyć do zwrócenia wartości wygenerowanych przez wyzwalacz.źródło
output
nie musisz tworzyć tabeli tymczasowej, aby przechowywać i sprawdzać wyniki. Po prostu zostawinto
część klauzuli wyjściowej, a wyświetli się ona w zestawie wyników.OUTPUT
jest „najlepsze”, o ile nie używasz wyzwalaczy i obsługuje się błędy, aleSCOPE_IDENTITY
jest najprostsze i bardzo rzadko ma problemyUważam, że najbezpieczniejszym i najdokładniejszym sposobem odzyskania wstawionego identyfikatora byłoby użycie klauzuli wyjściowej.
na przykład (zaczerpnięte z następującego artykułu MSDN )
źródło
OUTPUT
SQL Server 2005 zawiera stronę MSDN , więc wygląda na to, że jest to tylko SQL Server 2000 i wcześniejszeMówię to samo co pozostali, więc wszyscy mają rację, staram się tylko wyjaśnić.
@@IDENTITY
zwraca identyfikator ostatniej rzeczy wstawionej przez połączenie twojego klienta z bazą danych.Przez większość czasu działa to dobrze, ale czasami wyzwalacz pójdzie i wstawi nowy wiersz, o którym nie wiesz, i otrzymasz identyfikator z tego nowego wiersza, zamiast tego, który chcesz
SCOPE_IDENTITY()
rozwiązuje ten problem. Zwraca identyfikator ostatniej rzeczy, którą wstawiłeś do kodu SQL wysłanego do bazy danych. Jeśli wyzwalacze przejdą i utworzą dodatkowe wiersze, nie spowodują zwrotu niewłaściwej wartości. BrawoIDENT_CURRENT
zwraca ostatni identyfikator, który został wstawiony przez kogokolwiek. Jeśli jakaś inna aplikacja zdarzy się wstawić kolejny wiersz w niefortunnym czasie, otrzymasz identyfikator tego wiersza zamiast swojego.Jeśli chcesz grać bezpiecznie, zawsze używaj
SCOPE_IDENTITY()
. Jeśli będziesz trzymać się,@@IDENTITY
a ktoś zdecyduje się dodać wyzwalacz później, cały Twój kod się zepsuje.źródło
Najlepszym (czytaj: najbezpieczniejszym) sposobem uzyskania tożsamości nowo wstawionego wiersza jest użycie
output
klauzuli:źródło
scope_identity()
), aby uzyskać równoległe plany. Ten błąd został naprawiony ponad rok przed odpowiedzią.output
zamiastscope_identity()
. W odpowiedzi usunąłem FUD dotyczący grupowania.Dodaj
na końcu instrukcji wstawiania sql
odzyska to.
źródło
Gdy używasz Entity Framework, wewnętrznie korzysta z tej
OUTPUT
techniki, aby zwrócić nowo wstawioną wartość identyfikatoraWyniki wyjściowe są przechowywane w tymczasowej zmiennej tabeli, łączone z powrotem do tabeli i zwracają wartość wiersza z tabeli.
Uwaga: Nie mam pojęcia, dlaczego EF miałby wewnętrznie dołączyć efemeryczny stół z powrotem do prawdziwego stołu (w jakich okolicznościach te dwa nie pasują).
Ale tak właśnie działa EF.
Ta technika (
OUTPUT
) jest dostępna tylko w SQL Server 2008 lub nowszym.Edytuj - powód przyłączenia
Powodem, dla którego Entity Framework dołącza z powrotem do oryginalnej tabeli, zamiast po prostu używać
OUTPUT
wartości, jest to, że EF używa tej techniki również w celu uzyskaniarowversion
nowo wstawionego wiersza.Z optymistycznej współbieżności można korzystać w modelach struktury encji, używając
Timestamp
atrybutu: 🕗Po wykonaniu tej czynności Entity Framework będzie potrzebował
rowversion
nowego wiersza:Aby to odzyskać
Timetsamp
, nie możesz użyćOUTPUT
klauzuli.To dlatego, że jeśli na stole jest wyzwalacz, każde
Timestamp
WYJŚCIE będzie błędne:Zwrócony znacznik czasu nigdy nie będzie poprawny, jeśli masz wyzwalacz na stole. Więc należy użyć oddzielnego
SELECT
.I nawet jeśli byłeś skłonny ponieść niepoprawną konwersję wierszy, innym powodem do wykonania osobnego
SELECT
jest to, że nie możesz WYKONAĆrowversion
zmiennej zmiennej tabeli:Trzecim powodem jest symetria. Podczas wykonywania
UPDATE
na stole z wyzwalaczem nie można użyćOUTPUT
klauzuli. Próba wykonaniaUPDATE
za pomocąOUTPUT
nie jest obsługiwana i spowoduje błąd:Jedynym sposobem, aby to zrobić, jest
SELECT
oświadczenie uzupełniające :źródło
TurboEncabulators
:)MSDN
źródło
@@ TOŻSAMOŚĆ to ostatnia tożsamość wstawiona przy użyciu bieżącego połączenia SQL. Jest to dobra wartość, aby powrócić z procedury składowanej wstawiania, w której wystarczy wstawić tożsamość dla nowego rekordu, i nie przejmuj się, czy później zostanie dodanych więcej wierszy.
SCOPE_IDENTITY to ostatnia tożsamość wstawiona przy użyciu bieżącego połączenia SQL, aw bieżącym zakresie - to znaczy, jeśli wstawiono drugą tożsamość opartą na wyzwalaczu po wstawieniu, nie byłaby odzwierciedlona w SCOPE_IDENTITY, tylko wstawiona przez Ciebie wstawka . Szczerze mówiąc, nigdy nie miałem powodu, aby z tego korzystać.
IDENT_CURRENT (tablename) to ostatnia wstawiona tożsamość bez względu na połączenie lub zakres. Możesz użyć tego, jeśli chcesz uzyskać bieżącą wartość TOŻSAMOŚCI dla tabeli, do której nie wstawiłeś rekordu.
źródło
Nie mogę rozmawiać z innymi wersjami programu SQL Server, ale w 2012 r. Bezpośrednie wyświetlanie jest w porządku. Nie musisz zawracać sobie głowy tymczasowym stołem.
Nawiasem mówiąc, ta technika działa również podczas wstawiania wielu wierszy.
Wynik
źródło
OUTPUT
. Jeśli nie potrzebujesz tabeli tymczasowej, Twoje zapytanie jest znacznie prostsze.ZAWSZE używaj scope_identity (), NIGDY nie potrzebujesz niczego innego.
źródło
Utwórz,
uuid
a także wstaw go do kolumny. Następnie możesz łatwo zidentyfikować swój wiersz za pomocą UUID. To jedyne w 100% działające rozwiązanie, które możesz wdrożyć. Wszystkie pozostałe rozwiązania są zbyt skomplikowane lub nie działają w tych samych przypadkach brzegowych. Na przykład:1) Utwórz wiersz
2) Uzyskaj utworzony wiersz
źródło
uuid
bazy danych. Więc wiersz zostanie znaleziony szybciej.https://www.npmjs.com/package/uuid
.const uuidv4 = require('uuid/v4'); const uuid = uuidv4()
Innym sposobem na zagwarantowanie tożsamości wstawianych wierszy jest określenie wartości tożsamości i użycie opcji
SET IDENTITY_INSERT ON
a następnieOFF
. To gwarantuje, że wiesz dokładnie, jakie są wartości tożsamości! Dopóki wartości nie są używane, można je wstawić do kolumny tożsamości.Może to być bardzo przydatną techniką, jeśli ładujesz dane z innego źródła lub scalasz dane z dwóch baz danych itp.
źródło
Mimo że jest to starszy wątek, istnieje nowszy sposób, aby to zrobić, co pozwala uniknąć niektórych pułapek kolumny IDENTITY w starszych wersjach programu SQL Server, takich jak luki w wartościach tożsamości po ponownym uruchomieniu serwera . Sekwencje są dostępne w programie SQL Server 2016 i nowszym sposobem jest utworzenie obiektu SEKWENCJA za pomocą TSQL. Umożliwia to tworzenie własnych obiektów sekwencji numerycznych w SQL Server i kontrolowanie ich przyrostów.
Oto przykład:
Następnie w TSQL wykonaj następujące czynności, aby uzyskać identyfikator następnej sekwencji:
Oto linki do UTWÓRZ SEKWENCJĘ i NASTĘPNEJ WARTOŚCI DLA
źródło
Po wyciągnięciu instrukcji musisz to dodać. I upewnij się, że podana jest nazwa tabeli, do której wstawiane są dane. Otrzymasz bieżący wiersz, nie w którym wierszu wpływa teraz instrukcja wstawiania.
źródło