Stored procedure : assign date if passed parameters are null - sql

I am trying to assign values to stored procedure when the passed arguments are null.
If startDate or endDate is null, I want to assign values to them
Like
#StartDate = '1990-01-01'
#EndDate = DATEADD(YEARS, 30, GETDATE()) -- 30 years from now.
How can I do this?
CREATE OR ALTER PROCEDURE dbo.GetByProductID
(
#ProductID INT,
#StartDate DATETIME = NULL
#EndDate DATETIME = NULL
)
AS
SELECT ProductId, Name, InsertedDate, UpdatedDate
FROM Products
WHERE ProductId = #ProductID
AND InsertedDate > #startDate
AND UpdatedDate < #EndDate

CREATE OR ALTER PROCEDURE dbo.GetByProductID
(
#ProductID INT,
#StartDate DATETIME = NULL
#EndDate DATETIME = NULL
)
AS
set #StartDate = coalesce(#StartDate,'1990-01-01')
set #EndDate = coalesce(#EndDate,DATEADD(YEARS, 30, GETDATE())) -- 30 years from now.
SELECT ProductId, Name, InsertedDate, UpdatedDate
FROM Products
WHERE ProductId = #ProductID
AND InsertedDate > #startDate
AND UpdatedDate < #EndDate

Related

Trying to set default param value in stored procedure but errors on CONVERT

Wish to set default value in stored procedure but running into error, CONVERT doesn't seem to exist. CONVERT works in the body but not in the params section of the stored procedure. How do I set param #StartDate to a default of 24 months in the past?
CREATE PROCEDURE [dbo].[MyStoredProc]
#Id INT = NULL,
#startDate DATETIME = CONVERT(DATE, DATEADD(MONTH, -1 * 24, GETDATE())), -- last 24 months
#endDate DATETIME = CONVERT(DATE, GETDATE())
AS
BEGIN
SELECT #startDate;
END
GO
That works!
CREATE procedure [dbo].[MyStoredProc]
#Id int = null
,#startDate datetime = null
,#endDate datetime = null
as
begin
SET #startDate = ISNULL(#startDate, CONVERT(DATE, DATEADD(MONTH, -1*24, GETDATE())));
select #startDate;
END
GO

Displaying the number of valid results for a range of dates

I currently have a table with a creation date and a expiry date. I currently have a sql command to get the number of valid items for a given date.
select
count(id) ,CONVERT(date, getdate())
from
table
where
createDate < getdate() and expDate > getdate()
This returns the count and current date.
Is it possible to wrote a sql query that will return the result for a range of dates, say I if wanted to plot the number of valid items over a range of 15 days?
Thanks!
Try this:
create table #datelist (ValidDateCheck date, ValidResults int)
declare #startdate date = '1/1/2015'
declare #enddate date = '2/1/2015'
declare #interval int = 1 --Use 1 if you want every day between your dates, use 2 if you want every other day, etc.
declare #datecounter date = #startdate
declare #count int
while #datecounter <= #enddate
begin
set #count =
(select count(*)
from Table
where CrtDt <= #datecounter and ExpDt > #datecounter)
insert into #datelist values (#datecounter, #count)
set #datecounter = dateadd(dd, #interval, #datecounter)
end
select * from #datelist order by 1
It loops through all the dates in your range, counting valid results for each one.
Check this,
DECLARE #StartDate DATETIME,
#EndDate DATETIME;
SELECT #StartDate = '20110501'
,#EndDate = '20110801';
SELECT
DATEADD(d, x.number, #StartDate) AS MonthName1
,
x.number
FROM master.dbo.spt_values x
WHERE x.type = 'P'
AND x.number <= DATEDIFF(MONTH, #StartDate, #EndDate);
The above query give the list of dates between 2 dates.
As per your table and question, check this also.
declare #table table(id int,frdt datetime, todt datetime)
insert into #table values (1,GETDATE()-20, GETDATE()-19)
,(2,GETDATE()-9, GETDATE()-8)
,(3,GETDATE()+20, GETDATE()+18)
,(4,GETDATE(), GETDATE()-1)
,(5,GETDATE()-20, GETDATE())
,(6,GETDATE()-10, GETDATE()+10 )
select * from #table
declare #frdt datetime = null , #todt datetime = getdate()-10
select #frdt, #todt,* from #table
where
(#frdt is null or #frdt between frdt and todt)
and
(#todt is null or #todt between frdt and todt)
select #frdt = GETDATE()-15 , #todt = GETDATE()
select #frdt, #todt,* from #table
where
(#frdt is null or #frdt between frdt and todt)
and
(#todt is null or #todt between frdt and todt)

Determine if two parameters are null, then use parameters in the where clause

Good day, I receive 2 nullable date parameters in my stored procedure. #StartDate and #EndDate. I need to execute my procedure as normal if these two parameters are NULL, else the #StartDate param needs to be >= my StartDateTime value AND #EndDate param needs to be <= my EndDateTime value.
Below is a snippet of what I am trying to accomplish but are not sure of the syntax.
FROM DI_Intervention_Schedule S
WHERE
(
#ID IS NULL
OR S.[ID] = #ID
)
AND (
CASE #StartDate WHEN IS NOT NULL THEN
#StartDate >= S.[StartDateTime] AND #EndDate <= S.[EndDateTime]
END
)
Any help please?
Try below code :
FROM DI_Intervention_Schedule S
WHERE
(S.[ID] = #ID OR #ID IS NULL)
AND (( S.[StartDateTime] >= #StartDate AND S.[EndDateTime] <= #EndDate) OR #StartDate IS NULL )

T-SQL - Using CASE with Parameters in WHERE clause

I'm running a report on a Sales table:
SaleId INT | SalesUserID INT | SiteID INT | BrandId INT| SaleDate DATETIME
I'm having a nightmare trying to do something like this with a set of Nullable parameters #SalesUserID, #SiteId, #BrandID and two DateTime params.
Additional Point: Only ONE of the filter parameters will ever be passed as a Non-Null value.
SELECT * from Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate
AND
SalesUserID IN
(
Select SalesUserID FROM Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate
AND
CASE
WHEN #SalesUserId IS NOT NULL THEN SalesUserId = #SalesUserID
WHEN #SiteId Is Not Null THEN SiteId = #SiteId
ELSE BrandId = #BrandID
END
)
My use of CASE here smells bad but I'm not sure how to correct it. Can you please assist?
Thanks.
5arx
I don't think you want a CASE statement at all, but a compound conditional... Give this a shot and let me know:
select *
from Sales
where SaleDate between #StartDate and #EndDate
and
(
(#SalesUserId is not null and SalesUserId = #SalesUserID)
or (#SiteId is not null and SiteId = #SiteId)
or (BrandId = #BrandID)
)
If I understood you correctly, you want the three conditions either be NULL or checked for:
WHERE
/* ... */
AND SalesUserId = ISNULL(#SalesUserId, SalesUserId)
AND SiteId = ISNULL(#SiteId, SiteId)
AND BrandId = ISNULL(#BrandID, BrandID)
Be aware that this forces a table scan which might not be in your best interest.
This should work and use any index if you want to use CASE:
SELECT *
from Sales
WHERE SaleDate BETWEEN #StartDate AND #EndDate
AND SalesUserID = CASE WHEN #SalesUserID IS NULL THEN
SalesUserID ELSE #SalesUserID END
COALESCE() returns the 1st non NULL argument so you could;
...
WHERE SaleDate BETWEEN #StartDate AND #EndDate
AND SalesUserId = COALESCE(#SalesUserId, SalesUserId)
AND SiteId = COALESCE(#SiteId, SiteId)
AND BrandID = COALESCE(#BrandID, BrandId)
I would use a dynamic generated code in such a circumstance:
declare #SalesUserId int,#SiteId int,#StartDate datetime, #EndDate datetime,#BrandID int
declare #sql nvarchar(max)
set #sql = N'
SELECT * from Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate
AND
SalesUserID IN
(
Select SalesUserID FROM Sales
WHERE
SaleDate BETWEEN #StartDate AND #EndDate AND
' +
CASE
WHEN #SalesUserId IS NOT NULL THEN 'SalesUserId = #SalesUserID'
WHEN #SiteId Is Not Null THEN 'SiteId = #SiteId'
ELSE 'BrandId = #BrandID'
END
+')'
print #sql
exec sp_executesql #sql
, N'#SalesUserId int,
#SiteId int,
#StartDate datetime,
#EndDate datetime,
#BrandID int'
,#SalesUserId
,#SiteId
,#StartDate
,#EndDate
,#BrandID
This is generally a job for dynamic SQl if you want performance.
http://www.sommarskog.se/dynamic_sql.html
Try this:
SELECT *
from Sales
WHERE SaleDate BETWEEN #StartDate AND #EndDate
AND SalesUserID = CASE WHEN #SalesUserID IS NULL THEN
SalesUserID ELSE #SalesUserID END

SQL query date null check

I have the following stored procedure.
ALTER PROCEDURE [dbo].[spList_Report]
#id INT,
#startDate DATETIME = NULL,
#endDate DATETIME = NULL,
#includeStatus1 BIT,
#includeStatus2 BIT,
#includeStatus3 BIT,
#includeStatus4 BIT
AS
SET NOCOUNT ON
SELECT *
FROM
tblProducts as products
WHERE
product.intID = #id
AND product.dateMain >= #startDate
AND product.dateMain <= #endDate
If #startDate AND #endDate are both null then I want it to return the rows ignoring the date check in the where clause.
How?
This should do
AND product.dateMain >= ISNULL( #startDate, 0)
AND product.dateMain <= ISNULL( #endDate, product.dateMain + 1)
ISNULL yields the second value, if the first value is null.
Thus:
if #startDate is null, then dateMain must be bigger than 0 (1900-01-01)
if #endDate is null, then dateMain must be smaller than dateMain + 1 day
you can try something like this
ALTER PROCEDURE [dbo].[spList_Report]
#id INT,
#startDate DATETIME = NULL,
#endDate DATETIME = NULL,
#includeStatus1 BIT,
#includeStatus2 BIT,
#includeStatus3 BIT,
#includeStatus4 BIT
AS
SET NOCOUNT ON
SELECT *
FROM
tblProducts as products
WHERE
product.intID = #id
AND product.dateMain >= ISNULL( #startDate, product.dateMain )
AND product.dateMain <= ISNULL( #endDate, product.dateMain )
You can utilize an "or" in your Sql, but since this is a stored procedure:
If #startdate is null Or #enddate is null
begin
select without using a date range
end
Else
begin
select using date range
end
I would use Kris Krause's solution, but change the "IF" statement to use "AND". I think if you use the first two solutions the query engine may perform a table/index scan on the date fields. You want to keep your queries as concise as possible for best performance, so don’t run queries on unnecessary columns.
IF #startdate IS NULL AND #enddate IS NULL
BEGIN
SELECT * FROM tblProducts as products WHERE
product.intID = #id
END
ELSE
BEGIN
SELECT * FROM tblProducts as products WHERE
product.intID = #id
AND product.dateMain >= #startDate
AND product.dateMain <= #endDate
END