ADO.NET zapytanie zwracające pojedynczą wartość

 

W poprzednich postach omówiłem wykorzystanie metody ExecuteReader() wywoływanej na rzecz obiektu typu SqlCommand, która to zwracała obiekt typu SqlDataReader. Dysponowanie takim obiektem pozwala na analizę wyników zwróconych przez zapytanie. Kolejne dane z SqlDataReader’a odczytywane są wierszami, co sugeruje, że metoda ExecuteReader() powinna być stosowana wtedy, gdy chcemy pobrać z bazy danych wiele wierszy. Czasem jednak, wykorzystując do tworzenia zapytań np. funkcje agregujące oczekujemy, że zwrócona zostanie tylko jedna wartość. W takim wypadku nie ma sensu wykorzystywanie zbyt skomplikowanych rozwiązań, ręczne wykonywanie i analizowanie wyników zwróconych przez metodę ExecuteReader(). Obiekt typu SqlCommand posiada bowiem metodę   ExecuteScalar(), której zadaniem jest zwrócenie właśnie pojedynczej wartości.

Przykład:

Rozważmy stosowaną w poprzednich przykładach tabelę z przygotowanej bazy danych:

Id

FirstName

LastName

LoginName

Age

ExperienceLevel

1

NULL

NULL

Michal

18

2.2

3

Zbigniew

Kowalski

sa

NULL

3.3

Zmianie uległa jedynie wartość poziomu doświadczenia dla użytkownika o loginie ‘sa’ z wcześniejszej wartości 2.2 do 3.3. Celem przykładu jest zaimplementowanie funkcjonalności, która zwracałaby średni poziom zaawansowania użytkowników. Wiązać będzie się to z wykorzystaniem funkcji agregujących. Zapytanie (ściśle mówiąc łańcuch znakowy przechowujący zapytanie) będzie miało zatem następującą postać:

string strSql = "SELECT AVG(ExperienceLevel) FROM dbo.SimpleLogins";
Pojedynczą wartość można oczywiście uzyskać stosując metodę ExecuteReader(). Spójrzmy jak w tym przypadku wyglądałby stosowny kod.
 
using (SqlDataReader reader = cmd.ExecuteReader())
{
    //Take first row from reader
    reader.Read();

    //Assign result to ExperiencaLabel
    ExperienceLabel.Text = reader[0].ToString();
}

Przy takim podejściu należy utworzyć obiekt typu SqlDataReader, odczytać pierwszy wiersz (zakładamy, że zwrócony zostanie przynajmniej jeden), a także w przypadku gdy nie jest z jakiegoś powodu zastosowany blok using, pamiętać o zamknięciu odczytywanego strumienia. Wydaje się to być zbyt wiele zachodu do odczytania jednej wartości. Spójrzmy zatem co oferuje nam metoda ExecuteScalar():
 
ExperienceLabel.Text = cmd.ExecuteScalar().ToString();

Tak, zgadza się, wszystko za pomocą jednej linii kodu. Jak to możliwe? Otóż wywołanie metody ExecuteScalar() powoduje automatyczne utworzenie obiektu typu SqlDataReader i odczytanie z niego pożądanej wartości. Na zakończenie wywołania metoda ta ponadto sama zamyka i usuwa obiekt typu SqlDataReader. Wchodząc nieco głębiej w szczegóły metoda ExecuteScalar() wykonuje zapytanie zwracając przy tym pierwszą kolumnę z pierwszego wiersza otrzymanego wyniku. Dodatkowe kolumny i wiersze, nawet gdyby istniały, są ignorowane. Zwracany jest obiekt typu Object, stąd konieczne jest rzutowanie. W razie niepowodzenia przy odczycie wyrzucony zostanie wyjątek SqlException.

Wynikiem w przedstawionym przykładzie jest oczywiście wartość 2.750000, która wpisywana jest do utworzonej kontrolki ExperienceLabel.

Reklamy

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Zdjęcie na Facebooku

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Zdjęcie na Google+

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s

%d blogerów lubi to: