У меня есть поиск с тремя полями ввода (для аргументов, скажем, LastName, Last4Ssn и DateOfBirth). Эти три поля ввода находятся в динамической сетке, где пользователь может выбрать поиск одной или нескольких комбинаций этих трех полей. Например, пользователь может поиск на основе ниже представления:Как запросить с неизвестной комбинацией дополнительных параметров в SQL Server без курсоров?
LastName Last4Ssn DateOfBirth
-------- -------- -----------
Smith NULL 1/1/1970
Smithers 1234 NULL
NULL 5678 2/2/1980
В примере, первая строка представляет собой поиск по ЬазШате и DateOfBirth. Второй, по LastName и Last4Ssn. И, в-третьих, по Last4Ssn и DateOfBirth. Этот пример немного надуман, поскольку в реальном мире сценарий имеет четыре поля. По крайней мере, два поля должны быть заполнены (не беспокойтесь о том, как проверять) с данными поиска, и возможно, что заполнены поля все поля.
Без использования курсоров, как использовать эти данные для соединения с существующими таблицами с использованием значений с учетом значений в каждой строке в качестве фильтра? В настоящее время у меня есть курсор, который проходит через каждую строку вышеприведенной таблицы, выполняет соединение на основе столбцов, имеющих значения, и вставляет найденные данные в временную таблицу. Что-то вроде этого:
CREATE TABLE #results (
Id INT,
LastName VARCHAR (26),
Last4Ssn VARCHAR (4),
DateOfBirth DATETIME
)
DECLARE @lastName VARCHAR (26)
DECLARE @last4Ssn VARCHAR (4)
DECLARE @dateOfBirth DATETIME
DECLARE search CURSOR FOR
SELECT LastName, Last4Ssn, DateOfBirth
FROM #searchData
OPEN search
FETCH NEXT FROM search
INTO @lastName, @last4Ssn, @dateOfBirth
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #results
SELECT s.Id, s.LastName, s.Last4Ssn, s.DateOfBirth
FROM SomeTable s
WHERE Last4Ssn = ISNULL(@last4Ssn, Last4Ssn)
AND DateOfBirth = ISNULL(@dateOfBirth, DateOfBirth)
AND (
LastName = ISNULL(@lastName, LastName)
OR LastName LIKE @lastName + '%'
)
FETCH NEXT FROM search
INTO @lastName, @last4Ssn, @dateOfBirth
END
CLOSE search
DEALLOCATE search
Я надеялся, что там был какой-то способ, чтобы избежать курсор, чтобы сделать код немного более читаемым. Производительность не является проблемой, поскольку таблица, используемая для поиска, никогда не будет содержать более 5-10 записей, но я думаю, что для более чем нескольких было бы более эффективно запрашивать данные одновременно, а не один по очереди. Таблица SomeData
в моем примере может быть очень большой.
То, что я начал делать, прежде чем вы ответили. Поскольку таблица 'SomeData' является большой, она занимает около 4 секунд для запуска и в настоящее время выполняет сканирование индекса, поскольку есть только один индекс, который, по-видимому, использует, который охватывает связанные с ним поля. – Sumo
@sumo Я добавил новый запрос и 3 индекса, которые работают вместе, чтобы заставить SomeData получать доступ только к индексу. –
Новый запрос, похоже, не отвечает исходным требованиям, поскольку исходный запрос использует 'AND' между необязательными параметрами. Используя соединение там, вы фактически делаете 'OR', который не даст правильных результатов. Запрос должен 'И' как минимум два из поставляемых параметров, поэтому его особенно сложно оптимизировать. – Sumo