您在此处拥有的内容称为 Catch-all 或 "Kitchen Sink" 查询。最好使用参数化动态 SQL 来处理这些问题。
我假设您的所有参数都是可选的(尽管如果@FromDate 已通过,那么@ToDate 也应通过)。因此,您想要的很可能是这样的:
--Removed prefix, per comment under question
CREATE PROC dbo.Search_RatingAndReviewsReport (@Name nvarchar(200) = NULL, --I ASSUME that Tbl_CustomerRating.Name is an nvarchar too?
@FromDate date = NULL, --Why was this an nvarchar? How many dates exist with unicode characters?
@ToDate date = NULL)
AS BEGIN
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT CR.{List your columns}, --If you''re seeing braces, you haven''t replaced this as directed' + NCHAR(13) + NCHAR(10) + --Replace this with your columns, don't use * in a precompiled object
N' C.[Name]' + NCHAR(13) + NCHAR(10) +
--Created Date is already in your previous a.*, therefore no need to repeat it.
--If you want it in a specific format, then get your presentation layer to do that, not SQL Server
N'FROM dbo.Tbl_CustomerRating CR' + NCHAR(13) + NCHAR(10) + --Customer and Rating start with C and R, not "a"
N' JOIN dbo.Tbl_Customer C ON CR.CustomerId = C.CustomerId' + NCHAR(13) + NCHAR(10) + --Customer starts with C, not b. Also changed to a JOIN due to the WHERE
N'WHERE ';
--Now for the fun part, the dynamic WHERE
DECLARE @WHERE nvarchar(MAX) = N'';
IF @Name IS NOT NULL --If @Name isn't NULL, add it to the WHERE
SET @WHERE = @WHERE + NCHAR(13) + NCHAR(10) + N' AND C.[Name] = @Name'
IF @FromDate IS NOT NULL OR @ToDate IS NOT NULL --If either of the dates aren't NULL add it to the WHERE (note that is one is NULL then no results will be returned)
SET @WHERE = @WHERE + NCHAR(13) + NCHAR(10) + N' AND CR.CreatedDate BETWEEN @FromDate AND @ToDate'
SET @WHERE = STUFF(NULLIF(@WHERE,''),1,8,''); --The NULLIF will turn the value to NULL if no parameters were supplied
SET @SQL = @SQL + @WHERE + N';';
PRINT @SQL; --Your best friend
--EXEC sp_executesql @SQL, N'@Name nvarchar(200), @FromDate date, @ToDate date', @Name, @FromDate, @ToDate; --Uncomment to run the dynamic statement
END;
请注意,您需要消化该 SQL 中有 大量 的 cmets,并且您还需要更改大括号 ({}) 中的部分(根据相邻的评论)。
然后你可以测试运行它,你会得到以下结果:
EXEC dbo.Search_RatingAndReviewsReport;
不返回任何内容(没有 PRINT,不是数据集),因为没有参数
EXEC dbo.Search_RatingAndReviewsReport @Name = N'John Smith';
将运行以下 SQL:
SELECT CR.{List your columns}, --If you're seeing braces, you haven't replaced this as directed
C.[Name]
FROM Tbl_CustomerRating CR
JOIN Tbl_Customer C ON CR.CustomerId = C.CustomerId
WHERE C.[Name] = @Name;
EXEC dbo.Search_RatingAndReviewsReport @FromDate = '20190101', @ToDate = '20190601';
返回下面的 SQL:
SELECT CR.{List your columns}, --If you're seeing braces, you haven't replaced this as directed
C.[Name]
FROM Tbl_CustomerRating CR
JOIN Tbl_Customer C ON CR.CustomerId = C.CustomerId
WHERE CR.CreatedDate BETWEEN @FromDate AND @ToDate;
最后:
EXEC dbo.Search_RatingAndReviewsReport @Name = N'Jane Bloggs', @FromDate = '20190101', @ToDate = '20190601';
将运行 SQL:
SELECT CR.{List your columns}, --If you're seeing braces, you haven't replaced this as directed
C.[Name]
FROM Tbl_CustomerRating CR
JOIN Tbl_Customer C ON CR.CustomerId = C.CustomerId
WHERE C.[Name] = @Name
AND CR.CreatedDate BETWEEN @FromDate AND @ToDate;
dbo. 没有出现在上面打印的 SQL 中,因为我在粘贴上面执行的值之后将它添加到 SP 的定义中。