Where to add and declare variables to use them in dynamic SQL? - sql-server

I have created dynamic pivot sql that works well, but i still have a simple problem - how to change this line in dynamic part of sql WHERE DUE_DATE BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) AND DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0)) so that I can manage dates between using variables (f.e.: #startdate and #enddate). Where i should add and declare variables that will works in this place. Тhe goal is for the user to set the counting period by himself. Help. Any suggestions?
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #selectCols AS NVARCHAR(MAX)
DECLARE #query AS NVARCHAR(MAX)
DECLARE #DATANUO DATETIME
SET #DATANUO = '2021-12-01'
SELECT #selectCols = STUFF((SELECT ', ISNULL(' + QUOTENAME(DATEPART(DAY,DUE_DATE)) + ', 0) AS ' + QUOTENAME(DATEPART(DAY,DUE_DATE))
FROM [DB].[sbo].[SALES]
WHERE DUE_DATE BETWEEN #DATANUO AND EOMONTH(#DATANUO)
GROUP BY DUE_DATE
ORDER BY DUE_DATE
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(DATEPART(DAY,DUE_DATE))
FROM [DB].[sbo].[SALES]
WHERE DUE_DATE BETWEEN #DATANUO AND EOMONTH(#DATANUO)
GROUP BY DUE_DATE
ORDER BY DUE_DATE
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = ' SELECT Branch,' + #selectCols + ' FROM
(
SELECT Branch AS Branch, DATEPART(DAY,DUE_DATE) AS Diena, COUNT(*) AS Sales
FROM [DB].[sbo].[SALES]
WHERE DUE_DATE BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) AND DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0))
GROUP BY Branch, DUE_DATE
) src
PIVOT
(
SUM(Sales)
FOR Diena IN (' + #cols + ')
) p '
EXECUTE(#query)

Related

Creating Dynamic Pivot Table Column Names

I have created a pivot table with hard coded column names. The pivot table simply keeps a rolling sum of sales by qty (current month + 11 months back).
It was my first time using the PIVOT function properly and the code works fine.
SELECT
Item_Code_Desc,
ISNULL([Current],0) AS [Current],
ISNULL([1],0) AS [1],
ISNULL([2],0) AS [2],
ISNULL([3],0) AS [3],
ISNULL([4],0) AS [4],
ISNULL([5],0) AS [5],
ISNULL([6],0) AS [6],
ISNULL([7],0) AS [7],
ISNULL([8],0) AS [8],
ISNULL([9],0) AS [9],
ISNULL([10],0) AS [10],
ISNULL([11],0) AS [11]
FROM
(SELECT
CONCAT(ST.Code,' - ', ST.Description_1) AS Item_Code_Desc,
STT.ActualQuantity AS Qty,
CASE
WHEN MONTH(STT.TxDate) = MONTH(GETDATE()) THEN 'Current'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -1, GETDATE())) THEN '1'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -2, GETDATE())) THEN '2'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -3, GETDATE())) THEN '3'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -4, GETDATE())) THEN '4'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -5, GETDATE())) THEN '5'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -6, GETDATE())) THEN '6'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -7, GETDATE())) THEN '7'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -8, GETDATE())) THEN '8'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -9, GETDATE())) THEN '9'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -10, GETDATE())) THEN '10'
WHEN MONTH(STT.TxDate) = MONTH(DATEADD(MONTH, -11, GETDATE())) THEN '11'
ELSE '0'
END AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, -11, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
AND STT.Module = 'AR') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[Current])
) AS PVT
To make the output more dynamic, I wanted to rather show the month and year as the field heading, rather than just the 1,2,3 etc.
To attempt this, I first took out the original CASE, and used the CONCAT function to get the desired result
CONCAT(DATENAME(MONTH,STT.TxDate),' ',YEAR(STT.TxDate)) AS [Period],
Now that the sub-query was showing the transaction date in the format "mmmm yyyy", I wanted the table to pivot on this. I did start wondering how it was going to do this as I was reaching the end, as the column names are not hard coded anymore.
After trying
PIVOT (
SUM(P.Qty)
FOR CONCAT(DATENAME(MONTH,P.TxDate),' ',YEAR(P.TxDate))
) AS PVT
And many other variations I did do some research, and I see this process is slightly more complex than I thought.
I haven't used the STUFF and FOR XML PATH before. I have attempted to convert the above into the examples I have found on the net. But I'm trying in vein as I don't understand the core logic of what I am trying to do.
Please could I have assistance with not only how to get the pivot dynamic, but perhaps some notes to further understand what is happening. Really appreciate some help on this!
After Attempting
This is my attempt to get it right:
DECLARE
#Cols NVARCHAR(MAX),
#Query NVARCHAR(MAX),
#Module NVARCHAR = 'AR'
SELECT
#Cols = STUFF((SELECT DISTINCT ',' + 'CONCAT(DATENAME(MONTH, STT.TxDate),,YEAR(STT.TxDate))' + QUOTENAME(NAME)
FROM _bvSTTransactionsFull AS STT
WHERE STT.Module = 'AR'
FOR XML PATH (''), TYPE).VALUE('.','NVARCHAR(MAX)'),1,1,'')
SELECT
#Query = '
SELECT
Item_Code,
Item_Desc,
' +''''+ #Cols + '''''
FROM
(SELECT
ST.Code AS Item_Code,
ST.Description_1 AS Item_Desc,
STT.ActualQuantity AS Qty,
CONCAT(DATENAME(MONTH, STT.TxDate),,YEAR(STT.TxDate)) AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0,
GETDATE()), 0))
AND STT.Module = '+ #Module +') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ('+#cols+')
) AS PVT '
PRINT #Query
EXEC (#Query)
But I'm getting the following error:
Msg 207, Level 16, State 1, Line 7
Invalid column name 'NAME'.
Where am I off here?
Your result is correct above however, you will not have your columns sorted by the correct date...
The below would cater for that:
DECLARE
#Cols1 VARCHAR(MAX),
#Cols2 VARCHAR(MAX),
#Query VARCHAR(MAX),
#Period VARCHAR(MAX) = -13 ; --/ Select number of months to view back on (excluding current month) \--
declare #tmptbl table (PeriodDate datetime, col1 varchar(100), col2 varchar(100))
insert into #tmptbl (PeriodDate, col1, col2)
SELECT DISTINCT dPeriodDate,'ISNULL('+ QUOTENAME(CONCAT(DATENAME(MONTH, dPeriodDate),' ',YEAR(dPeriodDate)))+',0) AS' + QUOTENAME(CONCAT(DATENAME(MONTH, dPeriodDate),' ',YEAR(dPeriodDate))) col1
, QUOTENAME(CONCAT(DATENAME(MONTH, dPeriodDate),' ',YEAR(dPeriodDate))) col2
FROM _bvSTTransactionsFull AS S join _etblPeriod p on EOMONTH(s.TxDate) = p.dPeriodDate
WHERE S.Module = 'AR' AND S.TxDate > = DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
SELECT
#Cols1 = STUFF((SELECT ',' + col1
FROM #tmptbl order by PeriodDate
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ allows the first SELECT fields to have the ISNULL function and Alias \--
SELECT
#Cols2 = STUFF((SELECT ',' + col2
FROM #tmptbl order by PeriodDate
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ becasue of the need for ISNULL above, second #Cols needed for the Pivot (pivot cannot have ISNULL in it) \--
SELECT
#Query =
'SELECT
Item_Code_Desc,
'+#Cols1+'
FROM
(SELECT
CONCAT(ST.Code,'' - '', ST.Description_1) AS Item_Code_Desc,
STT.ActualQuantity AS Qty,
CONCAT(DATENAME(MONTH, STT.TxDate),'' '',YEAR(STT.TxDate)) AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, '+#Period+', DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
AND STT.Module = ''AR'') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ('+#cols2+')
) AS PVT '
PRINT #Query
EXEC (#Query)
I left the changes I made in small caps for you to see the changes...
Solved :)
DECLARE
#Cols1 VARCHAR(MAX),
#Cols2 VARCHAR(MAX),
#Query VARCHAR(MAX),
#Period VARCHAR(MAX) = -12 ; --/ Select number of months to view back on (excluding current month) \--
SELECT
#Cols1 = STUFF((SELECT DISTINCT ',' +'ISNULL('+ QUOTENAME(CONCAT(DATENAME(MONTH, S.TxDate),' ',YEAR(S.TxDate)))+',0) AS' + QUOTENAME(CONCAT(DATENAME(MONTH, S.TxDate),' ',YEAR(S.TxDate)))
FROM _bvSTTransactionsFull AS S
WHERE S.Module = 'AR' AND S.TxDate > = DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ allows the first SELECT fields to have the ISNULL function and Alias \--
SELECT
#Cols2 = STUFF((SELECT DISTINCT ',' + QUOTENAME(CONCAT(DATENAME(MONTH, S.TxDate),' ',YEAR(S.TxDate)))
FROM _bvSTTransactionsFull AS S
WHERE S.Module = 'AR' AND S.TxDate > = DATEADD(MONTH, -13, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
FOR XML PATH (''), TYPE).value('.','NVARCHAR(MAX)'),1,1,'') --/ becasue of the need for ISNULL above, second #Cols needed for the Pivot (pivot cannot have ISNULL in it) \--
SELECT
#Query =
'SELECT
Item_Code_Desc,
'+#Cols1+'
FROM
(SELECT
CONCAT(ST.Code,'' - '', ST.Description_1) AS Item_Code_Desc,
STT.ActualQuantity AS Qty,
CONCAT(DATENAME(MONTH, STT.TxDate),'' '',YEAR(STT.TxDate)) AS [Period]
FROM
_bvSTTransactionsFull AS STT
INNER JOIN
StkItem AS ST ON STT.AccountLink = ST.StockLink
WHERE
STT.TxDate >= DATEADD(MONTH, '+#Period+', DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))
AND STT.Module = ''AR'') AS P
PIVOT
(SUM(P.Qty)
FOR P.Period IN ('+#cols2+')
) AS PVT '
PRINT #Query
EXEC (#Query)

Convert nvarchar to datetime sql server

I try to convert 2016/07/15 (nvarchar format) to this datetime format 2016-07-15 00:00:00 in sql server. But i need the time part to be the current time. can any one help ?
This is my sp:
declare #DateTime varchar(50)
set #DateTime = '2016/07/15'
select convert(varchar, cast(#DateTime as datetime), 120)
You can use this:
declare #DateTime varchar(50)
set #DateTime = CONCAT('2016/07/15' , ' ', CONVERT(TIME, GETDATE()))
select #DateTime
select convert(varchar, cast(#DateTime as datetime2(7)), 120)
Or replace the CONCAT with:
set #DateTime = '2016/07/15' + ' ' + CONVERT(NVARCHAR(50), CONVERT(TIME, GETDATE()))
Try this...
Just concat time with your output
declare #DateTime varchar(50)
set #DateTime = '2016/07/15'
select convert(varchar, cast(#DateTime as datetime), 101) + ' ' + CONVERT(varchar, getdate(),108)
Try like this,
DECLARE #DateTime VARCHAR(50)
SET #DateTime = '2016/07/15'
SELECT DATEADD(day, 0, DATEDIFF(day, 0, #DateTime)) + DATEADD(day, 0 - DATEDIFF(day, 0, getdate()), getdate())

SQL Server Dynamic Pivot Query

I am creating a dynamic pivot query that shows the total NetAmount per Week of every Customers within a given date range. The problem is it doesn't ADD ALL the NetAmount within the Week. Here are the data of tblSampleSalesInvoices:
Here is my script.
CREATE PROCEDURE uspSalesWeeklySummary
(
#CustomerId INT,
#FromDate DATETIME,
#ToDate DATETIME
)
AS
SET NOCOUNT ON
DECLARE #Query AS VARCHAR(MAX)
DECLARE #DateStart DATETIME = #FromDate
DECLARE #tmp TABLE ([Date] VARCHAR(MAX))
DECLARE #Month VARCHAR(MAX)
DECLARE #Day VARCHAR(MAX)
DECLARE #ColumnHeader VARCHAR(MAX)
DECLARE #Headers VARCHAR(MAX)
WHILE DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101') <= DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #ToDate), '19050101')
BEGIN
SET #month = DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101'))
SET #day = CAST( DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX) )
SET #ColumnHeader = 'Week ' + CAST(DatePart(WEEK,#DateStart) AS VARCHAR(MAX)) + ' - ' + CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX)) + ' - ' + #month + ' - ' + #day
INSERT INTO #tmp ([Date])
VALUES (#ColumnHeader)
SET #DateStart = DATEADD(DD, 7, #DateStart)
END
SELECT #Headers = ISNULL(#Headers + ',','') + QUOTENAME(t.[Date])
FROM #tmp t
SET #Headers = #Headers + ',[Grand Total]'
SET #Query =
'
DECLARE #CustomerId INT = ' + CAST(#CustomerId AS VARCHAR) + '
DECLARE #FromDate DATETIME = CAST(''' + CAST(#FromDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #ToDate DATETIME = CAST(''' + CAST(#ToDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #Headers VARCHAR(MAX) = ''' + CAST(#Headers AS VARCHAR(MAX)) + '''
SELECT *
FROM
(
SELECT c.CustomerName AS CustomerName,
''Week '' + CAST(DatePart(WEEK,si.TransactionDate) AS VARCHAR(MAX)) + '' - ''
+ CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) + '' - ''
+ CAST(DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) + '' - ''
+ CAST(DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', si.TransactionDate), ''19050101'')) AS VARCHAR(MAX)) AS Header,
SUM(si.NetAmount) AS NetAmount
FROM tblSampleSalesInvoices si
LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE (si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101''))
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY c.CustomerName, si.TransactionDate
UNION ALL
SELECT c.CustomerName AS CustomerName,
''Grand Total'' AS Header,
SUM(si.NetAmount) AS NetAmount
FROM tblSampleSalesInvoices si
LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE (si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101''))
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY c.CustomerName
) AS BaseData
PIVOT
(
SUM(NetAmount)
FOR Header IN (' + #Headers + ')
) AS Pivoting'
EXEC (#Query)
GO
EXEC uspSalesWeeklySummary 0,'01/01/2016','02/01/2016'
In this script the SUM of NetAmount will be 10000 only because From the Day of Jan 1, 2016 until Feb 1,2016 only 1 transaction (TR0002) has been made. But when I place Dec 27,2015 and Feb 1,2016 in the parameters. It shows only the NetAmount of TR0001 instead of 25000 which the SUM of TR0001 and TR0002.
If you are looking for week numbers relative to a start date and can create # tables then this might suit
CREATE PROCEDURE uspSalesWeeklySummary
(
#CustomerId INT,
#FromDate DATETIME,
#ToDate DATETIME
)
AS
SET NOCOUNT ON
set datefirst 1
/*
create table tblSampleSalesInvoices (id int,transactionNo int,customerid int,TransactionDate date,netamount int)
insert into tblSampleSalesInvoices values
(1,1,1,'2015-12-29',15000),
(2,2,1,'2016-01-01',15000),
(3,3,2,'2016-03-01',15000),
(4,4,3,'2016-04-01',15000),
(5,5,4,'2016-06-01',15000),
(6,6,1,'2016-09-01',15000),
(7,7,2,'2016-10-01',15000),
(8,8,3,'2016-12-01',15000),
(9,9,4,'2017-01-01',15000),
(10,10,1,'2017-04-01',15000),
(11,11,2,'2017-07-01',15000),
(12,12,3,'2017-10-01',15000),
(13,13,4,'2017-12-01',15000)
*/
--declare #CustomerId INT = 1
--declare #FromDate DATETIME = '2015-12-27'
--declare #ToDate DATETIME = '2016-02-01'
DECLARE #Query AS VARCHAR(MAX)
DECLARE #DateStart DATETIME = #FromDate
IF OBJECT_ID(N'tempdb..#Tempdates') IS NOT NULL
BEGIN
DROP TABLE #Tempdates
END
declare #id int = 0
create table #tempdates (id int,[lodate] date, [hidate] date ,yyyy varchar(4), mm varchar(max), dd int,txt varchar(max))
DECLARE #Month VARCHAR(MAX)
DECLARE #Day VARCHAR(MAX)
DECLARE #ColumnHeader VARCHAR(MAX)
DECLARE #Headers VARCHAR(MAX)
WHILE DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101') <= DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #ToDate), '19050101')
BEGIN
set datefirst 1
SET #month = DATENAME(Month, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101'))
SET #day = CAST( DATEPART(DD, DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX) )
SET #ColumnHeader = 'Week ' + CAST(DatePart(WEEK,#DateStart) AS VARCHAR(MAX)) + ' - ' +
CAST(Year(DATEADD(WEEK, DATEDIFF(WEEK, '19050101', #DateStart), '19050101')) AS VARCHAR(MAX)) + ' - ' + #month + ' - ' + #day
set #id = #id + 1
insert into #tempdates (id,[lodate],[hidate],yyyy,mm,dd,txt)
values (#id,#datestart,dateadd(dd,6,#datestart),
year(#datestart),
datename(month,#datestart),day(#datestart),
'Week ' + cast(#id as varchar(2)) + ' - ' + cast(datename(month,#datestart) as varchar(max)) + ' - ' + cast(day(#datestart) as varchar(max))
)
SET #DateStart = DATEADD(DD, 7, #DateStart)
END
update #tempdates
set hidate = #todate where id = #id
SELECT #Headers = ISNULL(#Headers + ',','') + QUOTENAME(t.[txt])
FROM #tempdates t
SET #Headers = #Headers + ',[Grand Total]'
--select #headers headers
--select * from #tempdates
set #query =
'
DECLARE #CustomerId INT = ' + CAST(#CustomerId AS VARCHAR) + '
DECLARE #FromDate DATETIME = CAST(''' + CAST(#FromDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #ToDate DATETIME = CAST(''' + CAST(#ToDate AS VARCHAR) + ''' AS DATETIME)
DECLARE #Headers VARCHAR(MAX) = ''' + CAST(#Headers AS VARCHAR(MAX)) + '''
SELECT *
FROM
(
SELECT si.customerid,
t.txt as header,
SUM(si.NetAmount) AS NetAmount
FROM tblsamplesalesinvoices si
left join #tempdates t on si.Transactiondate between lodate and hidate
--LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101'')
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY -- c.CustomerName,
si.customerid
,
t.txt
UNION ALL
SELECT si.CustomerId,
''Grand Total'' AS Header,
SUM(si.NetAmount) AS NetAmount
FROM tblsamplesalesinvoices si
-- LEFT OUTER JOIN tblSampleCustomers c ON c.Id = si.CustomerId
WHERE (si.TransactionDate BETWEEN #FromDate AND DATEADD(WEEK, DATEDIFF(WEEK, ''19050101'', DATEADD(DD, 7 , #ToDate)), ''19050101''))
AND (si.CustomerId = #CustomerId OR #CustomerId = 0)
GROUP BY si.customerid
) s
PIVOT
(
SUM(NetAmount)
FOR Header IN (' + #Headers + ')
) AS Pivoting'
--select #query
exec (#query)
IF OBJECT_ID(N'tempdb..#Tempdates') IS NOT NULL
BEGIN
DROP TABLE #Tempdates
END
go
Please note dates are UK localised

Conversion failed when converting date in stored procedure

I have store procedure like this:
ALTER procedure [dbo].[ParkingSummary1] #startdate varchar(100), #enddate varchar(100) as begin
declare #date1 datetime = CONVERT(datetime, #startdate + ' 00:01:00.000', 120);
declare #date2 datetime = CONVERT(datetime, #enddate + ' 23:23:59.000', 120);
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT LocName, ' + #cols + '
from
( select l.LocName,Vtype from Transaction_tbl t join VType_tbl v on t.vtid = v.vtid
join dbo.Location_tbl l on t.locid=l.Locid where dtime between '''+ #date1+''' and '''+#date2+''' and Status = 5 ) d
pivot
(
count(Vtype)
for Vtype in (' + #cols + ')
) p ' exec sys.sp_executesql #query
end
.while am passing startand enddate like this:
#startdate = '2013-08-05',#enddate = '2013-08-08'
am getting error like this:Conversion failed when converting date and/or time from character string.
what is wrong with my stored procedure ? instead of Date1 and date2 if i pass startdate and enddate then it will work.but that time if i given same date then not coming any result
I would use SET DATEFORMAT YMD as the first line of your stored procedure.
ALTER procedure [dbo].[ParkingSummary1] #startdate varchar(100), #enddate varchar(100)
AS
BEGIN
SET DATEFORMAT DMY
declare #date1 datetime = CONVERT(datetime, #startdate + ' 00:01:00.000', 120);
declare #date2 datetime = CONVERT(datetime, #enddate + ' 23:23:59.000', 120);
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype)
from VType_tbl
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT LocName, ' + #cols + '
from
( select l.LocName,Vtype from Transaction_tbl t join VType_tbl v on t.vtid = v.vtid
join dbo.Location_tbl l on t.locid=l.Locid where dtime between '''+ #date1+''' and '''+#date2+''' and Status = 5 ) d
pivot
(
count(Vtype)
for Vtype in (' + #cols + ')
) p ' exec sys.sp_executesql #query
END
I had to replace
declare #date1 datetime = CONVERT(datetime, #startdate + ' 00:01:00.000', 120);
declare #date2 datetime = CONVERT(datetime, #enddate + ' 23:23:59.000', 120);
by
declare #date1 nvarchar(100) = convert(varchar, #startdate+' 00:00:00.000', 120)
declare #date2 nvarchar(100) = convert(varchar, #enddate+' 23:59:59.000', 120)

how to pass more than one value in sub query

I have a stored procedure like this:
ALTER procedure [dbo].[ParkingDeatailsReportnew]
#startdate nvarchar(100),
#enddate nvarchar(100)
as
begin
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols =
STUFF((SELECT distinct ',' + QUOTENAME(Vtype) from VType_tbl FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'')
set #query =
'SELECT Date, ' + #cols + '
from ( select v.Vtype, convert(date, dtime) as Date
from Transaction_tbl t inner join VType_tbl v on t.vtid = v.vtid where dtime between ''' + #startdate + ''' and ''' + #enddate +
'''and locid IN ' + (select CAST(l.Locid as varchar(max)) from Location_tbl l)
+ ' ) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
execute(#query)
end
While executing this am getting error like this:
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
How i can pass more than 1 value in my sub query?
I'd say your problem lays here:
(select CAST(l.Locid as varchar(max)) from Location_tbl l)
You're trying to form a string from an unknown amount of rows returned from that.
You could just make that part of the string.
Try this one -
ALTER PROCEDURE [dbo].[ParkingDeatailsReportnew]
#startdate NVARCHAR(100),
#enddate NVARCHAR(100)
AS BEGIN
DECLARE
#cols AS NVARCHAR(MAX)
, #query AS NVARCHAR(MAX)
SELECT #cols = STUFF((
SELECT DISTINCT ',' + QUOTENAME(Vtype)
FROM dbo.VType_tbl
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query =
'SELECT Date, ' + #cols + '
from (
select v.Vtype, convert(date, dtime) as Date
from Transaction_tbl t
join VType_tbl v on t.vtid = v.vtid
where dtime between ''' + #startdate + ''' and ''' + #enddate + '''
and locid IN (SELECT l.Locid FROM dbo.Location_tbl l)
) d pivot ( count(Vtype) for Vtype in (' + #cols + ') ) p '
EXEC sys.sp_executesql #query
END

Resources