SQL - 允许WHERE中的空值,但仍然基于其他参数返回数据

时间:2012-12-12 19:09:14

标签: sql sql-server-2005 parameters

这个对我来说有点难以正确解释所以请耐心等待。

我正在尝试创建一个动态SQL查询,以允许用户输入我为查询创建的各种参数的数据。如果填写了所有参数,我就会运行但我无法弄清楚如何允许其中一个或任何参数允许空值并仍然根据其他参数返回数据。例如,使用下面的查询信息,如果我将@Client参数设置为NULL,我希望为所有客户端返回相同的信息,而不是指定1个客户端。我希望除了日期字段之外的所有其他参数都有类似的功能,因为总是需要它们。

我想要允许空值的原因是此查询的最终产品,我正在使用VSrik中的Telerik编写报告,该报告将部署供我的公司使用。在telerik中,您可以允许参数在运行时为空。我们的目标是使这个报告对各种情况都有用,基本上这样做我不必在明年写出100个不同的查询,并且还可以让用户更多地控制/访问他们需要的内容。

这在SQL中是否可行?

这就是我现在所拥有的:

 DECLARE @Product int
    DECLARE @OrderDate1 datetime
    DECLARE @OrderDate2 datetime
    DECLARE @Status int
    DECLARE @Queue int
    DECLARE @Client int

    SET @Product = 86
    SET @OrderDate1 = '2012-09-01'
    SET @OrderDate2 = '2012-11-30'
    SET @Status = 80
    SET @Queue = 0
    SET @Client = 56156

    SELECT 
    CAST(oi.OrderID AS VARCHAR(MAX))+'.'+CAST(oi.OrderItemID AS VARCHAR(MAX)) AS OrderNumber
    ,CASE WHEN p.Abbreviation IS NULL THEN NULL
        ELSE p.Abbreviation END AS Product
    ,o.OrderDate
    ,v.ContactFirstName+' '+v.ContactLastName AS Vendor
    ,m.Description AS Status
    ,q.Description AS Queue

    FROM
    OrderItems oi
    JOIN Orders o (NOLOCK) ON o.OrderID = oi.OrderID
    JOIN Products p (NOLOCK) ON p.ProductID = oi.ProductID
    JOIN Vendors v (NOLOCK) ON v.VendorID = oi.VendorID
    JOIN Milestones m (NOLOCK) ON m.MilestoneID = oi.LastMilestoneID
    JOIN Queues q (NOLOCK) ON q.QueueID = oi.QueueID

    WHERE
    oi.ProductID in (@Product)
    and o.OrderDate BETWEEN @OrderDate1 and DATEADD(DD, 1, @OrderDate2)
    and oi.LastMilestoneID in (@Status)
    and oi.QueueID in (@Queue)
    and o.ClientID in (@Client)

DDL:

  CREATE TABLE OrderItems
(
OrderID int,
OrderItemID int,
ProductID int,
VendorID int,
LastMilestoneID int,
QueueID int
)
insert into OrderItems
Values(1234567, 1, 86, 105111, 80, 0)
CREATE TABLE Orders
(
OrderID int,
ClientID int,
OrderDate datetime
)
insert into orders
Values(1234567, 56156, '2012-11-08')
CREATE TABLE Products
(
ProductID int,
Abbreviation Varchar(20),

)
insert into products
Values(86, 'Product1')
CREATE TABLE Vendors
(
VendorID int,
ContactFirstName Varchar(20),
ContactLastName Varchar(20)
)
insert into vendors
Values(105111, 'john', 'doe')
 CREATE TABLE Milestones
 (
MilestoneID int,
Description Varchar(20)
)
insert into milestones
values(80, 'Status 1')
CREATE TABLE Queues
(
QueueID int,
Description Varchar(20)
)
insert into Queues
values(0, 'Queue1')

1 个答案:

答案 0 :(得分:4)

由于参数是单个值,我使用=而不是IN。一个非常简单的方法对于大型表格效果不佳:

WHERE (@Product IS NULL OR oi.ProductID = @Product)
  AND (@Status IS NULL OR oi.LastMilestoneID = @Status)
  ... etc

你想要表现的是Erland Sommarskog所说的“动态搜索条件”。阅读此article,了解您的所有选项以及每个选项的优点/缺点。