Tworzę procedurę przechowywaną do przeszukiwania tabeli. Mam wiele różnych pól wyszukiwania, z których wszystkie są opcjonalne. Czy istnieje sposób na utworzenie procedury składowanej, która sobie z tym poradzi? Powiedzmy, że mam tabelę z czterema polami: ID, Imię, Nazwisko i Tytuł. Mógłbym zrobić coś takiego:
CREATE PROCEDURE spDoSearch
@FirstName varchar(25) = null,
@LastName varchar(25) = null,
@Title varchar(25) = null
AS
BEGIN
SELECT ID, FirstName, LastName, Title
FROM tblUsers
WHERE
FirstName = ISNULL(@FirstName, FirstName) AND
LastName = ISNULL(@LastName, LastName) AND
Title = ISNULL(@Title, Title)
END
Ten rodzaj działa. Jednak ignoruje rekordy, w których FirstName, LastName lub Title mają wartość NULL. Jeśli tytuł nie jest określony w parametrach wyszukiwania, chcę dołączyć rekordy, w których tytuł ma wartość NULL - to samo dla FirstName i LastName. Wiem, że prawdopodobnie mógłbym to zrobić za pomocą dynamicznego SQL, ale chciałbym tego uniknąć.
tsql
optional-parameters
Corey Burnett
źródło
źródło
code
wykonać następującą instrukcję where : ISNULL (FirstName, ') = ISNULL (@FirstName,' ') - spowoduje to, że każda wartość NULL będzie pustym ciągiem i można je porównać za pomocą eq. operator. Jeśli chcesz uzyskać cały tytuł, jeśli parametr wejściowy ma wartość NULL, spróbuj czegoś takiego:code
FirstName = @FirstName LUB @FirstName IS NULL.Odpowiedzi:
Dynamicznie zmieniające się wyszukiwania oparte na danych parametrach to skomplikowany temat, a robienie tego w jedną stronę, nawet z niewielką różnicą, może mieć ogromny wpływ na wydajność. Kluczem jest użycie indeksu, zignorowanie zwartego kodu, zignorowanie obaw związanych z powtarzaniem kodu, należy przygotować dobry plan wykonania zapytania (użyć indeksu).
Przeczytaj to i rozważ wszystkie metody. Twoja najlepsza metoda będzie zależeć od parametrów, danych, schematu i faktycznego użycia:
Warunki dynamicznego wyszukiwania w T-SQL autorstwa Erlanda Sommarskoga
Klątwa i błogosławieństwa dynamicznego SQL autorstwa Erlanda Sommarskoga
Jeśli masz odpowiednią wersję programu SQL Server 2008 (SQL 2008 SP1 CU5 (10.0.2746) i nowszy), możesz użyć tej małej sztuczki, aby faktycznie użyć indeksu:
Dodaj
OPTION (RECOMPILE)
do zapytania, zobacz artykuł Erlanda , a SQL Server rozwiążeOR
od wewnątrz,(@LastName IS NULL OR LastName= @LastName)
zanim zostanie utworzony plan zapytań na podstawie wartości środowiska wykonawczego zmiennych lokalnych i można będzie użyć indeksu.Będzie to działać dla dowolnej wersji programu SQL Server (zwróć prawidłowe wyniki), ale uwzględniaj OPCJĘ (RECOMPILE), jeśli korzystasz z SQL 2008 SP1 CU5 (10.0.2746) i nowszych. OPCJA (RECOMPILE) ponownie skompiluje zapytanie, tylko wymieniona wersja zweryfikuje je na podstawie bieżących wartości zmiennych lokalnych w czasie wykonywania, co zapewni najlepszą wydajność. Jeśli nie w tej wersji SQL Server 2008, po prostu pozostaw tę linię wyłączoną.
źródło
Odpowiedź od @KM jest dobra, o ile to możliwe, ale nie w pełni odpowiada jednej z jego wczesnych rad;
Jeśli chcesz osiągnąć najlepszą wydajność, powinieneś napisać indywidualne zapytanie dla każdej możliwej kombinacji kryteriów opcjonalnych. Może to zabrzmieć ekstremalnie, a jeśli masz wiele opcjonalnych kryteriów, może być, ale wydajność jest często kompromisem między wysiłkiem a wynikami. W praktyce może istnieć wspólny zestaw kombinacji parametrów, które mogą być kierowane za pomocą niestandardowych zapytań, a następnie ogólne zapytanie (jak w przypadku innych odpowiedzi) dla wszystkich innych kombinacji.
Zaletą tego podejścia jest to, że w typowych przypadkach obsługiwanych przez niestandardowe zapytania zapytanie jest tak wydajne, jak to tylko możliwe - nie ma wpływu na niespełnione kryteria. Ponadto indeksy i inne ulepszenia wydajności mogą być ukierunkowane na określone zapytania na zamówienie, a nie próbować zaspokoić wszystkie możliwe sytuacje.
źródło
Możesz to zrobić w następującym przypadku:
jednak zależą od danych, lepiej lepiej utworzyć dynamiczne zapytanie i wykonać je.
źródło
Pięć lat spóźnienia na przyjęcie.
Jest o tym mowa w podanych linkach akceptowanej odpowiedzi, ale myślę, że zasługuje na jednoznaczną odpowiedź na SO - dynamiczne budowanie zapytania w oparciu o podane parametry. Na przykład:
Ustawiać
Procedura
Stosowanie
Plusy:
Cons:
Nie bezpośrednia odpowiedź, ale związana z problemem, czyli dużym obrazem
Zazwyczaj te przechowywane procedury filtrowania nie są zmiennoprzecinkowe, ale są wywoływane z jakiejś warstwy usług. Pozostawia to opcję przeniesienia logiki biznesowej (filtrowania) z SQL do warstwy usługi.
Jednym z przykładów jest użycie LINQ2SQL do wygenerowania zapytania w oparciu o dostarczone filtry:
Plusy:
Cons:
źródło
Przedłuż swój
WHERE
stan:tj. łącz różne przypadki z warunkami logicznymi.
źródło
Działa to również:
źródło