0

这对我来说有点难以正确解释,所以请多多包涵。

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

我想允许空值的原因是这个查询的最终产品,我正在使用 VS 2010 中的 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')
4

1 回答 1

4

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

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

您尝试执行的是 Erland Sommarskog 所称的“动态搜索条件”。阅读本文,了解您的所有选项以及每个选项的优缺点。

于 2012-12-12T19:14:58.320 回答