2013-01-12 6 views
9

Pracuję nad projektem ASP.NET (C#) z SQL Server 2008.Powrót ostatni zapisany identyfikator bez użycia drugą kwerendę

Kiedy wstawić wiersz do tabeli w bazie danych, chciałbym uzyskać identyfikator ostatniego wstawienia, który jest tablicą IDENTYFIKACJA (Auto inkrementowany).

nie chcę użyć innego zapytania, i zrobić coś jak ...

SELECT MAX(ID) FROM USERS; 

Bo - choć to tylko jedno zapytanie - czuje lame ...

Po włożeniu coś Zwykle używam ExecuteNonQuery(), która zwraca liczbę dotkniętych wierszy.

int y = Command.ExecuteNonQuery(); 

nie jest sposobem na powrót ostatni zapisany identyfikator bez użycia innej kwerendy?

+2

http://stackoverflow.com/a/9319609/284240 –

+2

Dla każdego, kto zastanawia się dlaczego Wybierz MAX (ID) jest to zły pomysł, ponieważ to tworzy sytuacji wyścigu. Jeśli ktoś inny wstawi w tym samym czasie, drugie zapytanie może zostać wykonane po następnej wstawce, zwracając zły identyfikator –

Odpowiedz

18

Większość ludzi to zrobić w następujący sposób:

INSERT dbo.Users(Username) 
VALUES('my new name'); 

SELECT NewID = SCOPE_IDENTITY(); 

(. Albo zamiast zapytania, przypisując że do zmiennej)

Więc tak naprawdę nie ma dwóch pytań: przy stole ...

jest również sposób:

INSERT dbo.Users(Username) 
OUTPUT inserted.ID 
VALUES('my new name'); 

Nie będzie naprawdę móc pobrać ten z ExecuteNonQuery, choć.

+1

+1. Ostatni sposób jest szczególnie dobry, ponieważ można wstawić wiele wierszy. – TomTom

+1

+1. Nie wspominając o tym, że możesz także * wypisać * ** n ** inne kolumny (tak, czasami jest to przydatne). – talles

5

Można zwrócić identyfikator jako parametr wyjściowy z procedury składowanej, np. @userId int output

Następnie po wkładce, SET @userId = scope_identity()

+0

-1. Procedura składowana zamiast - po prostu pytanie o wartość. Gratulacje, ty jsut generujesz koszmar utrzymania. – TomTom

+1

@TomTom Nie jestem pewien, zgadzam się, że procedura przechowywana jest koszmar utrzymania. Wszystko zależy od tego, czy chcesz wprowadzić zmiany SQL w procedurze przechowywanej, czy wprowadzić zmiany w kodzie ad hoc w aplikacji, rekompilować, ponownie wdrażać itd. –

+3

@ TomTom Nie używam LINQ (nie jestem programistą), ale Zrobiłem dużo rozwiązywania problemów wydajności dla ludzi, którzy mają. I w ogóle nie mówię o testowaniu. Czy naprawdę chcesz mi powiedzieć, że jeśli DBA musi wprowadzić zmiany w logice SQL (powiedzmy, dodaj wskazówkę do indeksu lub nastąpiła zmiana schematu, którą musi włączyć zapytanie), wdrażanie tych zmian w C# jest będzie łatwiej? Dlaczego programista aplikacji i autor T-SQL muszą być tą samą osobą? –

4
  • mimo że jest tylko jedno zapytanie - czuje lame ...

To faktycznie jest źle, jak można mieć wiele iserts nakładających.

To jedna rzecz, którą zawsze lubię zabawnie - ludzie nie czytający dokumentacji.

SELECT SCOPE_IDENTITY() 

zwraca ostatnią wartość tożsamości wygenerowaną w określonym zakresie i jest poprawna pod względem składniowym. Jest również odpowiednio udokumentowany.

Czy nie ma sposobu na zwrócenie ostatniego wstawionego identyfikatora bez użycia innego zapytania?

Tak. Poproś o numer w partii saame SQL.

INSERT (blablab9a); SELECT SCOPE_IDENTITY(); 

jako JEDEN ciąg.ExecuteScalar.

Możesz mieć więcej niż jedno zapytanie SQL w jednej partii.

+1

Czy możesz edytować swoją odpowiedź tak, aby było bardziej przyjazne dla C#? Ponieważ wyobrażam sobie SqlReader teraz w mojej głowie ... w jaki sposób będę mógł przeczytać SELECT SCORE_IDENTITY()? –

+0

@AliBassam Ucząc się języka C#. ExecuteScalar zwraca wartość, która jest pierwszą kolumną pierwszego rolaNo potrzeby obsługi SqlReader. Nic nie jest "przyjazne dla C#" w poznawaniu podstaw ADO.NET, wiesz. http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalar.aspx – TomTom

2

Jeśli chcesz wykonać zapytanie z kodu C# &, aby uzyskać ostatnio wstawiony identyfikator, musisz znaleźć następujący kod.

SqlConnection connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
     connection.Open(); 
     string sql = "Insert into [Order] (customer_id) values (" + Session["Customer_id"] + "); SELECT SCOPE_IDENTITY()"; 
     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = connection; 
     cmd.CommandText = sql; 
     cmd.CommandType = CommandType.Text; 
     var order_id = cmd.ExecuteScalar(); 

     connection.Close(); 
     Console.Write(order_id); 
Powiązane problemy