如果参数为null,如何返回所有记录

Ezi*_*Ezi 7 sql-server

以下是我的SP:

Alter PROCEDURE GetList 
(

@FromDate date = null,
@ToDate date = null

)
AS

Select * FROM CallList c
Where c.CallDate > @FromDate and c.CallDate < @ToDate 
Run Code Online (Sandbox Code Playgroud)

如果没有通过日期过滤器,我想获得所有记录.

我该怎么办?

Col*_*kay 15

你可以这样做:

SELECT * FROM CallList c
WHERE (c.CallDate > @FromDate OR @FromDate IS NULL) AND 
      (c.CallDate < @ToDate OR @ToDate IS NULL)
Run Code Online (Sandbox Code Playgroud)

这也使您可以将其中一个日期留空而不是另一个.

  • 注意OR重问题 - 他们有咬人的倾向. (2认同)

Nat*_*lus 6

你会做以下事情

SELECT * 
FROM CallList AS C
WHERE (@FromDate IS NULL OR c.CallDate > @FromDate)
AND (@ToDate IS NULL OR c.CallDate < @ToDate)
Run Code Online (Sandbox Code Playgroud)


Wil*_*l A 3

几个可行的选择:

您可以将@FromDate@ToDate分别设置为非常早或非常晚的日期,它们分别为 NULL。

您可以使用 sp_executesql 并根据需要构造带参数的动态查询字符串,例如

DECLARE @Sql NVARCHAR(MAX) = 'SELECT * FROM CallList C WHERE 1 = 1 '

IF @FromDate IS NOT NULL
BEGIN
  SET @Sql += ' AND C.CallDate > @xFromDate'
END

IF @ToDate IS NOT NULL
BEGIN
  SET @Sql += ' AND C.CallDate < @xToDate'
END

EXEC sp_executesql @Sql, N'@xFromDate DATETIME, @xToDate DATETIME', @xFromDate = @FromDate, @xToDate = @ToDate
Run Code Online (Sandbox Code Playgroud)

后一种方法比到处使用 OR 的性能更好,因为包含 OR 的查询最终总是会得到非常糟糕的优化 - 它们可能适用于一组特定的参数,但通常不是一刀切的。

  • +1 正确构建带有参数的 SQL 字符串,然后使用 sp_executesql - 很多人只是注入值并忽略其后果。 (5认同)