晚了五年。
在提供的接受答案的鏈接中提到了它,但我認爲它應該在SO上得到明確的答案 - 根據提供的參數動態構建查詢。例如: -
設置
-- drop table Person
create table Person
(
PersonId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_Person PRIMARY KEY,
FirstName NVARCHAR(64) NOT NULL,
LastName NVARCHAR(64) NOT NULL,
Title NVARCHAR(64) NULL
)
GO
INSERT INTO Person (FirstName, LastName, Title)
VALUES ('Dick', 'Ormsby', 'Mr'), ('Serena', 'Kroeger', 'Ms'),
('Marina', 'Losoya', 'Mrs'), ('Shakita', 'Grate', 'Ms'),
('Bethann', 'Zellner', 'Ms'), ('Dexter', 'Shaw', 'Mr'),
('Zona', 'Halligan', 'Ms'), ('Fiona', 'Cassity', 'Ms'),
('Sherron', 'Janowski', 'Ms'), ('Melinda', 'Cormier', 'Ms')
GO
程序
ALTER PROCEDURE spDoSearch
@FirstName varchar(64) = null,
@LastName varchar(64) = null,
@Title varchar(64) = null,
@TopCount INT = 100
AS
BEGIN
DECLARE @SQL NVARCHAR(4000) = '
SELECT TOP ' + CAST(@TopCount AS VARCHAR) + ' *
FROM Person
WHERE 1 = 1'
PRINT @SQL
IF (@FirstName IS NOT NULL) SET @SQL = @SQL + ' AND FirstName = @FirstName'
IF (@LastName IS NOT NULL) SET @SQL = @SQL + ' AND FirstName = @LastName'
IF (@Title IS NOT NULL) SET @SQL = @SQL + ' AND Title = @Title'
EXEC sp_executesql @SQL, N'@TopCount INT, @FirstName varchar(25), @LastName varchar(25), @Title varchar(64)',
@TopCount, @FirstName, @LastName, @Title
END
GO
使用
exec spDoSearch @TopCount = 3
exec spDoSearch @FirstName = 'Dick'
優點:
- 容易編寫和理解
- 彈性 - 易於產生用於棘手的濾波查詢(例如動態TOP)
缺點:
沒有直接回答問題,而是涉及到問題又名大畫面
通常,這些過濾存儲過程不會浮動,而是從某個服務層調用。這留下了將業務邏輯(過濾)從SQL移到服務層的選項。基於所提供的過濾器
- 動態生成的查詢:
一個實例是使用LINQ2SQL成基於提供的濾光器的查詢:
public IList<SomeServiceModel> GetServiceModels(CustomFilter filters)
{
var query = DataAccess.SomeRepository.AllNoTracking;
// partial and insensitive search
if (!string.IsNullOrWhiteSpace(filters.SomeName))
query = query.Where(item => item.SomeName.IndexOf(filters.SomeName, StringComparison.OrdinalIgnoreCase) != -1);
// filter by multiple selection
if ((filters.CreatedByList?.Count ?? 0) > 0)
query = query.Where(item => filters.CreatedByList.Contains(item.CreatedById));
if (filters.EnabledOnly)
query = query.Where(item => item.IsEnabled);
var modelList = query.ToList();
var serviceModelList = MappingService.MapEx<SomeDataModel, SomeServiceModel>(modelList);
return serviceModelList;
}
優點。沒有parameter sniffing或recompile提示需要
- 比較容易寫那些在OOP世界
- 通常表現友好,因爲「簡單」的查詢將發行(適當的索引仍需要雖然)
缺點:
- LINQ2QL限制可能達到並強制降級到LINQ2Objects或根據情況要回純SQL解決方案
- LINQ的粗心寫作可能會產生可怕的查詢(或許多查詢,如果導航屬性加載)
看一看這裏: http://stackoverflow.com/questions/11396919/building-dynamic-where-clause在存儲過程/ 25473624#25473624 – 2014-09-03 12:24:54
請嘗試以下語句: 'code' ISNULL(FirstName,')= ISNULL(@FirstName,'') - 這將使每個NULL 爲空字符串,可以通過等式進行比較。運營商。 如果你想獲得所有標題如果輸入參數爲空,然後嘗試這樣的事情: 'code'FirstName = @FirstName或@FirstName IS NULL。 – baHI 2016-01-13 10:58:18