How to do condition in SQL Server stored procedure - sql-server-2008

I have a stored procedure in which I need to implement a conditional WHERE clause.
I have a #name parameter, #startdate and #enddate parameters.
How can I write conditions:
if #name is null and #startdate & #enddate is given then return data for date range.
if #name is given and #startdate & #enddate is null then return data for the name
if #name and #startdate & #enddate is given then return data where name and date range are evaluated
Here is my current procedure
alter procedure dbo.sp_emp
#name varchar(50),
#startdate date,
#enddate date
as
begin
select *
from employee
where
Name = #name
and dob between #startdate and #enddate
end

I think COALESCE solves your problem.
alter procedure dbo.sp_emp
#name varchar(50),
#startdate date,
#enddate date
as
begin
select *
from employee
where Name = (COALESCE(#name, name))
AND dob between COALESCE(#startdate, dob) and COALESCE(#enddate, dob)
end
ISNULL version
alter procedure dbo.sp_emp
#name varchar(50),
#startdate date,
#enddate date
as
begin
select *
FROM employee
WHERE Name = ISNULL(#name, name)
AND dob between ISNULL(#startdate, dob) AND ISNULL(#enddate, dob)
end

You can do it this way:
DECLARE #query NVARCHAR(2048);
SET #query = 'select * from employee where Name = ''' + #name + '''';
IF #startdate IS NOT NULL AND #enddate IS NOT NULL
SET #query += ' AND dob between ''' + #startdate + ''' and ''' + #enddate '''';
EXECUTE(#query);
You should take care yours vars about SQL Injection.

Related

SSRS show list of weeks

Is there a way I can create a list of weeks (param):w1,W2,... based on another param list (years), so the first list is for the years and the second is for the weeks corresponding to the chosen year.
For example if I choose 2017 from my first list my second list (weeks) should be updated with labels W1,W2,... & the values are the corresponding dates in the given year.
Try this ...
declare #year as int
declare #startdate as datetime
declare #wk as int
declare #endwk as datetime
declare #tbl as table (
tbl_wk int,
tbl_Monday datetime
)
set #endwk= (SELECT DATEPART(wk, GETDATE())+1)
set #wk = 1
set #year = '2017'
set #startdate = CAST (cast(#year as varchar(4))+ '/01/01 00:00:00' as datetime)
while (#wk < #endwk)
begin
insert into #tbl (tbl_wk,tbl_Monday)
select #wk,DATEADD(wk, DATEDIFF(wk,0,#startdate), 0) as monday--MondayOfCurrentWeek,
set #wk = #wk+1
set #startdate = #startdate+7
end
select * from #tbl
You could adapt this to create a table in SQL and then reference this in your report.
Note: You could include Year in an outer loop if you need dates from more than one year
declare #year as int
declare #startdate as datetime
declare #wk as int
declare #tbl as table (
tbl_wk int,
tbl_Monday datetime
)
set #wk = 1
set #year = '2017'
set #startdate = CAST (cast(#year as varchar(4))+ '/01/01 00:00:00' as datetime)
while (#wk < 53)
begin
insert into #tbl (tbl_wk,tbl_Monday)
select #wk,DATEADD(wk, DATEDIFF(wk,0,#startdate), 0) as monday--MondayOfCurrentWeek,
set #wk = #wk+1
set #startdate = #startdate+7
end
select * from #tbl

SQL Asking To Declare Variable That Is Declared

I am attempting to run this SQL Syntax, but I keep getting an error of:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#startDate".
However, it looks to me that the variable is already declared at the beginning of my procedure. Why is the error being thrown, and what do I need to do to fix it?
I am using this syntax to call my stored procedure:
exec [dbo].[DoThis] '01/01/2015','01/31/2015'
And this is full procedure which presents compile error above.
ALTER Procedure [dbo].[DoThis]
(
#startDate datetime,
#endDate datetime
)
As
Declare #storename varchar(500), #dblocation varchar(500), #sql varchar(max)
Select storename, dblocation
INTO #allstores
FROM tbl_allstores
where sales >= '1,000,000'
Declare c1 Cursor For
Select storename, dblocation
FROM #allstores
Open c1
Fetch Next From c1 Into #storename, #dblocation
While ##FETCH_STATUS = 0
Begin
Set #sql = 'Insert Into #storeinfo (storename, employeename, employeeaddress, employeephone) '
+'Select '''+#storename+''' As ''storename'', '
+'employeename, employeeaddress, employeephone '
+'From '+#dblocation+' '
+'where employeestatus = ''Active'' '
+'and CAST(hiredate As Date) BETWEEN CAST(#startDate As Date) AND CAST(#endDate As Date) '
Print(#sql)
exec(#sql)
Fetch Next From c1 Into #storename, #dblocation
End
Close c1
Deallocate c1
Select * from #storeinfo
Drop Table #allstores
Drop Table #storeinfo
When you exec(#sql) this creates a new context with its own local variables, and you have not passed the #startDate value into that context.
Instead, declare parameters for your SQL string like this:
exec sp_executesql #sql, '#startDate datetime, #endDate datetime',
#startDate, #endDate;
These names will now be available to your SQL, and the parameters will be passed to them.
This method is better because it treats the variables as parameters which is safer because it reduces the risk of SQL Injection.
As an additional tip, you should also pass #storeName as a parameter. As far as I know you cannot pass #dbname as a parameter, so you should instead ensure that it is quoted correctly.
So the full thing would be:
Set #sql = 'Insert Into #storeinfo (storename, employeename, employeeaddress, employeephone) '
+' Select #storename As ''storename'', '
+' employeename, employeeaddress, employeephone '
+' From '+QUOTENAME(#dblocation)+' '
+' where employeestatus = ''Active'' '
+' and CAST(hiredate As Date) '
+' BETWEEN CAST(#startDate As Date) AND CAST(#endDate As Date) '
Print(#sql)
exec sp_executesql #sql,
'#startDate datetime, #endDate datetime, #storeName nvarchar(100)',
#startDate, #endDate, #storeName;
Changing to:
+'and CAST(hiredate As Date) BETWEEN CAST(''' + #startDate + ''' As Date) AND CAST(''' + #endDate + ''' As Date) '
I would think would work, or at least be close. Your issue is #startDate and #endDate are not actually declared within the separate scope that is executing your dynamic sql.
Basically exec(#sql) is a separate scope from the stored proc scope that is actually declaring your #startDate and #endDate.

Check Each Date In Date Range

In SQL Server 2008 I have a startdate and an enddate being passed to my procedure. I need to check each date in the range to see if it exists in my validworkday table. I have no clue where to begin on this, but this is how start/end day are set-up
Declare #startdate date, #enddate date
Set #startdate = '01/01/2015'
Set #enddate = '04/16/2015'
Now how can I iterate each date in this span to see if validworkday = true for it? The check I would need to run is like so (checking each date)
Select isvalidworkday
from validworkdays
where date = '01/01/2015'
Select isvalidworkday
from validworkdays
where date = '01/02/2015'
This is syntax that I found from #Incidently years ago (I don't remember where that original post is, but hopefully this will be enough to give the credit), that I still use today. All I did was slightly tweak his syntax to insert the data into a temp table and add a cursor to iterate each individual date.
DECLARE #DateFrom smalldatetime, #DateTo smalldatetime, #firstdate date;
SET #DateFrom='20000101';
SET #DateTo='20081231';
-------------------------------
WITH T(date)
AS
(
SELECT #DateFrom
UNION ALL
SELECT DateAdd(day,1,T.date)
FROM T
WHERE T.date < #DateTo
)
SELECT date
INTO #AllDates
FROM T OPTION (MAXRECURSION 32767);
Declare c1 Cursor For
Select date
FROM #AllDates
Open c1
Fetch Next From c1 Into #firstdate
While ##FETCH_STATUS = 0
Begin
--Do whatever processing you need here
Fetch Next From c1 Into #firstdate
End
Close c1
Deallocate c1
Code should only live in one place and not be rewritten. Create functions (once) like GetAllIntsBetween(), GetAllMonths(), GetAllDates(), etc. Then used them like:
DECLARE #startdate date = '01/01/2015', #enddate date = '04/16/2015'
SELECT allDates.TheDate,
isnull(v.isvalidworkday, false) AS isvalidworkday
FROM dbo.GetAllDates(#startdate, #enddate) AS allDates
LEFT JOIN validworkdays AS v
ON allDates.TheDate = v.MyDate
The GetAllDates() would be:
CREATE FUNCTION dbo.GetAllDates(#Start DATETIME, #End DATETIME)
RETURNS
#AllDates TABLE
(
TheDate DATETIME
)
AS
BEGIN
IF #Start > #End
BEGIN
DECLARE #Temp DATETIME
SET #Temp = #Start
SET #Start = #End
SET #End = #Temp
END
WHILE #Start <= #End
BEGIN
INSERT INTO #AllDates
VALUES(#Start)
SET #Start = DATEADD(DAY, 1, #Start)
END
RETURN
END
(note: can change DATETIME to DATE)

pulling variable in the select statement

I am trying to Pull #variable in select statement.
ex:
DECLARE #STARTDATE DATE
SELECT #STARTDATE = '8/1/2013'
DECLARE #ENDDATE DATE
SELECT #STARTDATE = '8/31/2013'
SELECT 'Results for DOS Serving' + #STARTDATE + 'to' + #EndDate
Any help please?
Thanks.
You can't just add string data and dates. You have to convert your dates to a string datatype first. (Also, in your code you never set #ENDDATE.
Something like this should get you close.
DECLARE #STARTDATE DATE
SELECT #STARTDATE = '8/1/2013'
DECLARE #ENDDATE DATE
SELECT #ENDDATE = '8/31/2013'
SELECT 'Results for DOS Serving ' + CONVERT(varchar, #STARTDATE, 110) + ' to ' + CONVERT(varchar, #EndDate, 110)
DECLARE #STARTDATE DATE
SET #STARTDATE = '8/1/2013'
DECLARE #ENDDATE DATE
SET #ENDDATE = '8/31/2013'
SELECT 'Results for DOS Serving ' + CONVERT(varchar(20), #STARTDATE, 110) + ' to ' + CONVERT(varchar(20), #EndDate, 110)

Date Wise Report in SQL server 2008

How to get following output ?
[1],[2],[3],[4],[5],[6],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17]
,[18],[19],[20]
,[21],[22],[23],[24],[25],[26],[27],[28],[29],[30]
Need to fetch all dates from given month in sql server
I want to display daily Date Wise report
Example :
If I pass date as '11/01/2012' then it should return above result
and if I pass December than 31 days.
Very unclear question but try
DECLARE #epoch DATETIME = '20130101'
;WITH cte AS
(
SELECT #epoch DateKey
UNION ALL
SELECT DATEADD(D, 1, DateKey)
FROM cte
WHERE MONTH(DATEADD(D, 1, DateKey))=MONTH(#epoch)
)
SELECT * FROM cte
try below code
declare #date datetime = '09/10/2012'
declare #noofdays int
select #noofdays =datediff(day, #date, dateadd(month, 1, #date))
DECLARE #startDate DATETIME=CAST(MONTH(#date) AS VARCHAR) + '/' + '01/' + + CAST(YEAR(#date) AS VARCHAR) -- mm/dd/yyyy
DECLARE #endDate DATETIME= CAST(MONTH(#date) AS VARCHAR) + '/' + cast(#noofdays as varchar) + '/' + CAST(YEAR(#date) AS VARCHAR)
;WITH Calender AS
(
SELECT #startDate AS CalanderDate
UNION ALL
SELECT CalanderDate + 1 FROM Calender
WHERE CalanderDate + 1 <= #endDate
)
SELECT [Date] = CONVERT(VARCHAR(10),CalanderDate,25)
FROM Calender
OPTION (MAXRECURSION 0)
I am able to find out answer my self....
Thanks Buddy for trying to help me...
DECLARE #COLSPIVOT AS NVARCHAR(MAX)=''
declare #MaxDate int
set #MaxDate=(SELECT day(DATEADD(ms,-2,DATEADD(MONTH, DATEDIFF(MONTH,0,'8/1/2013')+1,0)))
AS [Current Month])
declare #i int =1
while (#i<=#MaxDate)
begin
set #COLSPIVOT=#COLSPIVOT+'['+convert(varchar(10),#i)+']'
if(#i!=#MaxDate)
begin
set #COLSPIVOT=#COLSPIVOT+','
end
set #i=#i+1
end
select #COLSPIVOT