Запрос фильтра SQL
-
19-09-2019 - |
Вопрос
У меня есть таблица с несколькими полями в ней.Я пытаюсь создать фильтр поиска в asp.net чтобы пользователь мог выполнять поиск по одному или комбинации полей.Итак, по сути, я хочу создать единую хранимую процедуру, которая принимает 4 параметра, и она добавит параметр к предложению WHERE, если оно не равно null...
Пример таблицы содержит 4 столбца, Col1 Col2 Col3 Col4
Я надеюсь, что есть способ сделать это с помощью одной хранимой процедуры вместо того, чтобы создавать по одной для каждой возможной комбинации.
Я пробовал что-то подобное, что неверно, но это то, что у меня пока получилось.
Спасибо!
CREATE PROCEDURE [dbo].[Search]
@Col1 int,
@Col2 int,
@Col3 int,
@Col4 int
AS
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT *
FROM
[dbo].[TestTable]
WHERE
1=1
CASE
WHEN @Col1 IN NOT NULL
THEN AND [Col1] = @Col1
WHEN @Col2 IN NOT NULL
THEN AND [Col2] = @Col2
WHEN @Col3 IN NOT NULL
THEN AND [Col3] = @Col3
WHEN @Col4 IN NOT NULL
THEN AND [Col4] = @Col4
END
Решение 5
Я благодарю вас всех за ваши ответы.Однако я сделал это немного по-другому.Я надеюсь, что это кому-то поможет!Вот как я это сделал:
CREATE PROCEDURE [dbo].[TestTable_Search]
@Col1 int,
@Col2 uniqueidentifier,
@Col3 datetime,
@Col4 datetime
AS
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT *
FROM
[dbo].[TestTable]
WHERE
[Col1] = COALESCE(@Col1, Col1) AND
[Col2] = COALESCE(@Col2, Col2) AND
[Col3] >= COALESCE(@Col3 + "00:00:00", Col3) AND
[Col4] <= COALESCE(@Col4 + "23:59:59", Col4)
Другие советы
Используйте тот факт, что или короткое замыкание.Я предположил, что -1 - это недопустимое значение.
CREATE PROCEDURE [dbo].[Search]
@Col1 int = -1,
@Col2 int = -1,
@Col3 int = -1,
@Col4 int = -1
AS
Begin
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT *
FROM
[dbo].[TestTable]
WHERE
(@Col1 = -1 OR [Col1] = @Col1)
and
(@Col2 = -1 OR [Col2] = @Col2)
and
(@Col3 = -1 OR [Col3] = @Col3)
and
(@Col4 = -1 OR [Col4] = @Col4)
END
поиск - это один из редких вариантов, которые я проповедую, используя либо динамический sql, либо создавая вашу sql-строку в коде.если у вас есть полностью sproc-среда, используйте динамический sql в вашем sproc.параметризируйте его и используйте sp_executeSQL для его запуска, чтобы избежать SQL-инъекции
Вы можете сделать это с помощью метода, аналогичного тому, что у вас есть:
WHERE
CASE
WHEN @Col1 IS NULL THEN true
ELSE [Col1] = @Col1
END
AND
CASE
WHEN @Col2 IS NULL THEN true
ELSE [Col2] = @Col2
END
...
Или вы можете сделать его намного проще, хотя, возможно, и менее читабельным:
WHERE (@Col1 IS NULL OR [Col1] = @Col1])
AND (@Col2 IS NULL OR [Col2] = @Col2])
AND ...
Для этого вам пришлось бы использовать динамический SQL:
CREATE PROCEDURE [dbo].[Search]
@Col1 int,
@Col2 int,
@Col3 int,
@Col4 int
AS
DECLARE @SQL nvarchar(MAX)
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET @SQL = 'SELECT *
FROM [dbo].[TestTable]
WHERE 1=1 '
IF @Col1 IS NOT NULL
SET @SQL = @SQL + ' AND Col1 = ''' + @Col1 + ''' '
IF @Col2 IS NOT NULL
SET @SQL = @SQL + ' AND Col2 = ''' + @Col2 + ''' '
IF @Col3 IS NOT NULL
SET @SQL = @SQL + ' AND Col3 = ''' + @Col3 + ''' '
IF @Col4 IS NOT NULL
SET @SQL = @SQL + ' AND Col4 = ''' + @Col4 + ''' '
exec sp_executesql @SQL
END
Имейте в виду, что это сопряжено с опасностями, включая внедрение SQL, а также множеством других проблем с разрешениями, которые могут возникнуть, поскольку это динамический SQL, но это единственный способ выполнить это на уровне базы данных.Если вы хотите создать свой запрос на прикладном уровне (на C #), вы можете защищаться от атак SQL-инъекций гораздо более тщательно.
Некоторые динамические ссылки SQL, которые могут помочь вам понять недостатки:
http://www.sommarskog.se/dynamic_sql.html http://slashstar.com/blogs/tim/archive/2006/10/12/The-Prevalence-and-Dangers-of-SQL-Injection.aspx