Using SQL query gives error message - sql-server

I'm trying to create a report with iReport by using below query which runs fine on SSRS reports. I'm new to JasperReports. How can I declare variables inside the report query? Here is my SQL query:
Declare #SDate as Date
Declare #EDate as Date
Declare #JNumber as Char(8)
set #SDate = case When #StartDate > '1/1/2000' Then #StartDate Else GETDATE() End
set #EDate = case When #EndDate > '1/1/2000' Then #EndDate Else GETDATE() End
set #JNumber = ISNULL(#JobNumber, '')
select Distinct
j.JobNumber, j.CustomerRep, j.JobStatus, j.StatusDate, a.Answer14 'Ship Time' ,j.LastShippedDate, Cast(m.ExpectedDate as Date) 'ShipDate',
m.CustomerCode, RTrim(m.CustLongName) , RTrim(m.[Description]) 'JobName', RTrim(m.PONumber) 'PONumber', m.ProductCode, m.QuantityOrdered, a1.answer8'Pages'
from JobExtra j (NOLOCK)
Join JobMaster m (nolock) on m.JobNumber = j.JobNumber
where (#JNumber != '' AND #JNumber = j.JobNumber)
And #SDate <= Cast(ISNULL(ce.sStartDate, m.StartDate) As Date)
And #EDate >= Cast(ISNULL(ce.sStartDate, m.StartDate) As Date)
order by Case When #Sort = 'Ship Date' Then m.ExpectedDate When #Sort = 'Start Date' Then m.StartDate Else j.JobNumber End
, j.JobNumber, ce.sEndDate, ce.sEndTime, ce.sStartDate
The error is:
Error:java.sql.SQLException:Must Declare the scalar variable #StartDate

Seems like you have missed two variables.Please Declare variables #StartDate And #EndDate similarly like #SDate and #Edate
Ex:
Declare #StartDate Date
Declare EndDate Date
Please try it once
Thanks,
Dhana

Related

Running data for 1 year dates in SQL Server

I have a procedure where I have calls data for each day. From this procedure I wrote another procedure to insert and update in the destination table.
We have a job which runs for every day. But now I need to run the data for past 1 year (each day).
Below are my parameters in insert update procedure - if I need to get data for 18th my parameters values are like below
,#StartDate datetime = '2020-04-18'
,#EndDate datetime = '2020-04-19'
,#SkillLevel varchar(10)='Total'
,#Region varchar(20) = 'US'
If I need to get data for 17th my parameters values are like below
,#StartDate datetime = '2020-04-17'
,#EndDate datetime = '2020-04-18'
,#SkillLevel varchar(10)='Total'
,#Region varchar(20) = 'US'
Like this to get data for last 1 year I need to run the code for 365 days which takes huge effort
Could anyone suggest how to pass dates individually for 1 year with some loop.
Try this:
DECLARE #DataSource TABLE
(
[StartDate] DATE
);
DECLARE #BegDate DATE
,#EndDate DATE;
SELECT #BegDate = '2020-01-01'
,#EndDate = '2020-12-31';
DECLARE #EndNumber BIGINT;
SELECT #EndNumber = DATEDIFF(DAY, #BegDate, #EndDate);
INSERT INTO #DataSource ([StartDate])
SELECT TOP (#EndNumber) DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY T1.[number])-1, #BegDate)
FROM master..spt_values T1
CROSS JOIN master..spt_values T2;
WHILE EXISTS(SELECT 1 FROM #DataSource)
BEGIN;
SELECT TOP 1 #BegDate = [StartDate]
,#EndDate = DATEADD(DAY, 1, [StartDate])
FROM #DataSource;
--
EXEC [stored_precedure] #StartDate = #BegDate
,#EndDate = #EndDate
,#SkillLevel ='Total'
,#Region = 'ES'
--
DELETE FROM #DataSource
WHERE [StartDate] = #BegDate;
END;

Using the Where Statement on a Created Variable

I have the following code that creates the Checkin_day variable from CHECKIN_DATE_TIME. I'd like to only select 'Sundays' from the newly created Checkin_day variable but I'm getting an invalid column name error (because it is not a variable within the dataset). What can I add to my code so that I can select only records that fall on a 'Sunday'? Is this a declare issue or do I need to sub-query?
use EMTCQIData
DECLARE #StartDate Date
DECLARE #EndDate Date
Set #StartDate = '01/01/2018'
Set #EndDate = '12/31/2018'
SELECT *,
Format([CHECKIN_DATE_TIME],'dddd') AS [Checkin_Day]
FROM ED_TAT_MASTER
WHERE (CHECKIN_DATE_TIME > #StartDate and CHECKIN_DATE_TIME < #EndDate) AND
Checkin_Day = '*Sunday*'
Try querying the actual column, not the alias.
DECLARE #StartDate Date
DECLARE #EndDate Date
Set #StartDate = '01/01/2018'
Set #EndDate = '12/31/2018'
SELECT *,
FORMAT([CHECKIN_DATE_TIME], 'dddd') AS [Checkin_Day]
FROM
ED_TAT_MASTER
WHERE
(CHECKIN_DATE_TIME > #StartDate and CHECKIN_DATE_TIME < #EndDate)
AND FORMAT([CHECKIN_DATE_TIME], 'dddd') = 'Sunday' -- <- here
Also you can query by using DATEPART like DATEPART(dw, [CHECKIN_DATE_TIME]) = 0
https://www.w3schools.com/sql/func_sqlserver_datepart.asp
Add an AND to your WHERE clause to only get records that fall on Sunday.

Get monthly attendance for an employee

I have a query that a guy helped here in developing which gives fine result. I want to use this query in a function which later I want to use in a procedure.
CREATE FUNCTION [dbo].[fnGetWorkedDays] (#StartDate datetime, #EndDate datetime)
RETURNS int
AS
BEGIN
DECLARE #dateFrom datetime
DECLARE #dateTo datetime
SET #dateFrom = #StartDate
SET #dateTo = #EndDate
DECLARE #DAYSWORKED INT
SELECT #DAYSWORKED = (
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
)T
GROUP BY EmpId
ORDER BY EmpId)
RETURN ISNULL(#DAYSWORKED,0)
END
The very first error I am getting is that
Msg 1033, Level 15, State 1, Procedure fnGetWorkedDays, Line 24
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
I removed ORDER BY then I got another error says
Msg 116, Level 16, State 1, Procedure fnGetWorkedDays, Line 25
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I suggest you to go though this to understand more on table valued functions vs scalar valued function Difference between scalar, table-valued, and aggregate functions in SQL server?
Regarding your scenario, you should be writing a table values function for this like following.
CREATE FUNCTION [dbo].[fnGetWorkedDays]
(
#StartDate AS DATETIME,
#EndDate datetime
)
RETURNS TABLE
AS
RETURN
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
)T
GROUP BY EmpId
To use the function you can write your queries like following.
DECLARE #StartDate datetime
DECLARE #EndDate datetime
SET #StartDate = '2018-01-01'
SET #EndDate = '2018-01-31'
select * from [dbo].[fnGetWorkedDays](#StartDate,#EndDate)
If you want this to work as a scalar value function, in that case you need to pass EmpId as parameter like following.
CREATE FUNCTION [dbo].[fnGetWorkedDaysEmpWise]
(
#StartDate AS DATETIME,
#EndDate datetime,
#EmpId INT
)
RETURNS INT
AS
BEGIN
DECLARE #RetunCount INT
SELECT #RetunCount = COUNT(DISTINCT CAST(TimeIn AS DATE))
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
AND EmpID=#EmpId
RETURN #RetunCount
END
And you can use it directly in your select clause like following.
DECLARE #StartDate datetime
DECLARE #EndDate datetime
SET #StartDate = '2018-01-01'
SET #EndDate = '2018-01-31'
SELECT [dbo].[fnGetWorkedDaysEmpWise](#StartDate,#EndDate,1)
Is this what you are looking for .?
CREATE FUNCTION [dbo].[fnGetWorkedDays] (#StartDate datetime, #EndDate datetime)
RETURNS #DaysWorked TABLE
(
Empid Int,
DaysWorked Int
)
AS
BEGIN
insert into #DaysWorked (Empid,DaysWorked)
SELECT EmpId, COUNT(*) as DaysWorked
FROM
(
SELECT DISTINCT EmpId,CAST(TimeIn AS DATE) AS [Date]
FROM myTable
WHERE TimeIn IS NOT NULL
AND CAST(TimeIn AS DATE) BETWEEN #StartDate AND #EndDate
)T
GROUP BY EmpId
ORDER BY EmpId
RETURN
END
select * from [fnGetWorkedDays]('2018-01-01','2018-01-31')

How to set columns from dynamic query results

I am writing a query to calculate running totals of a few things over time. The time increments are in weekly buckets (every monday), however as time goes on, nothing needs to be in the past. This means my weekly buckets will be floating and always staying in the future. I have seen a couple links for how to setup a PIVOT function, however all of those examples the columns are fixed values. How do I get my query results to be displayed as my column names?
Here is my code which outputs what I need my column names to be. I set the increment to "1" to get just 4 results for testing, but will probably open it up to 12 months.
DECLARE #Startdate as date
DECLARE #Enddate as date
SET #Startdate = getdate()
SET #Enddate = DATEADD(Month,1,#StartDate)
;WITH cte(myDate) AS ( SELECT CASE WHEN DATEPART(Day,#StartDate) = 1 THEN #StartDate
ELSE DATEADD(Week,DATEDIFF(Week,0,#StartDate)+1,0) END AS myDate
UNION ALL
SELECT DATEADD(Week,1,myDate)
FROM cte
WHERE DATEADD(Week,1,myDate) <= #EndDate )
SELECT CONVERT(date,myDate) AS BuildWeek
FROM cte
OPTION (MAXRECURSION 0)
You will have to go dynamic.
You are missing some vital details. So I hope this will help with some guidance.
Below is a modified version of an answer from earlier today.
Declare #Startdate as date,#Enddate as date
Set #Startdate = getdate()
Set #Enddate = DATEADD(Month,1,#StartDate)
Declare #SQL varchar(max) = ''
Declare #Col varchar(max) = '
,[Title] = sum(case when Date between ''[DateR1]'' and ''[DateR2]'' then [YourField] else null end)'
;with cte(myDate) as (
Select Case When DatePart(Day,#StartDate) = 1 Then #StartDate Else DateAdd(Week,DateDiff(Week,0,#StartDate)+1,0) end as myDate
Union All
Select DateAdd(Week,1,myDate)
From cte
Where DateAdd(Week,1,myDate) <= #EndDate
)
Select #SQL = #SQL + Replace(Replace(Replace(#Col,'[DateR1]',DateR1),'[DateR2]',DateR2),'Title',Title)
From (Select DateR1 = cast(myDate as Date)
,DateR2 = DateAdd(DAY,6,cast(myDate as Date))
,Title = 'Week Of '+Substring(DateName(WEEKDAY,myDate),1,3)+' '+Substring(DateName(MONTH,myDate),1,3)+' '+cast(Day(myDate) as varchar(5))
From cte
) A
Set #SQL = 'Select ID'+#SQL+'
From YourTable
Group By ID
'
Print #SQL
--Exec(#SQL)
Returns the following SQL which would be executed
Select ID
,[Week Of Mon Sep 26] = sum(case when Date between '2016-09-26' and '2016-10-02' then [YourField] else null end)
,[Week Of Mon Oct 3] = sum(case when Date between '2016-10-03' and '2016-10-09' then [YourField] else null end)
,[Week Of Mon Oct 10] = sum(case when Date between '2016-10-10' and '2016-10-16' then [YourField] else null end)
,[Week Of Mon Oct 17] = sum(case when Date between '2016-10-17' and '2016-10-23' then [YourField] else null end)
From YourTable
Group By ID

How to declare dates in SQL multiple value

I am trying to create my SQL syntax so that we can have versatile input. I figured out how to do it for one set date and it worked.
my syn is:
DECLARE #MyDay AS VARCHAR(50);
DECLARE #NextDay AS VARCHAR(50);
SET #MyDay = '8/30/2016';
SET #NextDay = DATEADD(d, 1, #MyDay);
However, I'm stuck with how to do it for multiple dates. Ideally I would like to put in a range of date, and from that it will scan the records, i.e. set range between oct 1st and oct 5th.
I'm using SQL Server Management Studio 2008
If you just want a series of days and next days between 8/30/16 and 9/5/16, you can use a derive table method like below.
declare #n int;
declare #StartDate datetime, #EndDate datetime;
set #n = 5;
set #StartDate = '20160830';
set #EndDate = dateadd(day, #n, #StartDate);
select cast(dateadd(day, number, #StartDate) as date) as MyDate,
cast(dateadd(day, number + 1, #StartDate) as date) as MyNextDate
from
(select distinct number from master.dbo.spt_values
where name is null
) n
where dateadd(day, number, #StartDate) < #EndDate;
Alternately you can use a temp table, table variable to store your dates, or a cte as well.
A recursive cte imlementation example is given below. Please note you would want to set MAXRECURSION option if you have a long date range as default for max recursion is 100.
declare #n int;
declare #StartDate datetime, #EndDate datetime;
set #n = 5;
set #StartDate = '20160830';
set #EndDate = dateadd(day, #n, #StartDate);
;with DateSeq as
(
select cast(#StartDate as date) as MyDate
union all
select dateadd(day , 1, MyDate) AS MyDate
from DateSeq where dateadd (day, 1, MyDate) < #EndDate
)
select MyDate, dateadd(day , 1, MyDate) AS NextDate
from DateSeq;
A temp table implementation example is as below.
declare #MyDateRange table(MyDate date);
Insert into #MyDateRange values('8/30/2016')
Insert into #MyDateRange values('9/1/2016')
Insert into #MyDateRange values('9/2/2016')
Insert into #MyDateRange values('9/3/2016')
Insert into #MyDateRange values('9/4/2016')
select MyDate, dateadd(day, 1, MyDate) as NextDate from #MyDateRange

Resources