This one is a little hard for me to explain correctly so please bear with me.
I am trying to create a dynamic SQL query to allow users to input data for various parameters i am creating for the query. I have it running if all the parameters are filled in but i cannot figure out how to allow for one or any of these parameters to allow a null value and still return data based on the other parameters. For example, using the query info below, if i set the @Client Parameter to NULL, iwould want the same info to return for all clients instead of specifying 1 client. I would want a similar function for all of the other parameters except the date fields, as those would always be required.
The reason i want to allow for null values is the final product of this query, i am writing a report using Telerik in VS 2010 which will be deployed for my company to use. In telerik you can allow a parameter to be null at runtime. The goal is to make this report useful for various situations, basically making it so i dont have to write 100 different queries over the next year and also giving the user more control/access over what they need.
Is this possible in SQL?
here is what i have right now:
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')
Since the parameters are single values, I’d use
=rather thanIN. A very simple approach which will work poorly for large tables is:What you are trying to perform is what Erland Sommarskog terms as “dynamic search conditions”. Read this article for all your options and the benefits/downsides of each.