Conversion failed when converting date and/or time from character string while Pivot - sql

I have the following SQL query:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#OID AS NVARCHAR(MAX) = '(105, 106)',
#startDate DATETIME = DATETIMEFROMPARTS(2017, 11, 01, 17, 0, 0, 0),
#endDate DATETIME = DATETIMEFROMPARTS(2017, 11, 25, 17, 0, 0, 0)
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(Point)
FROM Value
GROUP BY Point
ORDER BY Point
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = 'SELECT timestamp,' + #cols + ' from
(
select timestamp, point, valuenumeric
from value where point in ' + #OID + ' and Timestamp between ' +
#startDate + ' and ' + #endDate + '
) x
pivot
(
avg(valuenumeric)
for point in (' + #cols + ')
) p '
execute(#query);
But I am getting this error:
Msg 241, Level 16, State 1, Line 16
Conversion failed when converting date and/or time from character string.

The issue is not in these lines, the issue in the dynamic sql part where you are appending the datetime data types #startdate and #enddate to strings. It should be:
....
Timestamp between ''' +
CONVERT(NVARCHAR(50), #startDate, 121)+ ''' and ''' + CONVERT(NVARCHAR(50),#endDate, 121) + '''
) x
...
You need also to add more ' so that the query is composed correctly as a dynamic sql query.
So your full query will be:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#OID as NVARCHAR(MAX) = '(105, 106)',
#startDate datetime = convert(datetime,'01-11-2017 6:10:00 PM',105),
#endDate datetime = convert(datetime,'30-11-2017 6:10:00 PM',105);
select #cols = STUFF((SELECT ',' + QUOTENAME(Point)
from Value
group by Point
order by Point
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set #query = 'SELECT timestamp,' + #cols + ' from
(
select timestamp, point, valuenumeric
from value where point in ' + #OID + ' and Timestamp between ''' +
CONVERT(NVARCHAR(50), #startDate, 121)+ ''' and ''' + CONVERT(NVARCHAR(50),#endDate, 121) + '''
) x
pivot
(
avg(valuenumeric)
for point in (' + #cols + ')
) p ';
execute(#query);
Demo.

You need to explicitly cast the datetime to varchar before concatenating with string
Also you need to append two more single quotes around the datetime parameter to enclose the date with single quotes.
To avoid all these hassle, I would suggest to use parameterised sql.
set #query = 'SELECT timestamp,' + #cols + ' from
(
select timestamp, point, valuenumeric
from value where point in ' + #OID + ' and Timestamp between
#startDate and #endDate
) x
pivot
(
avg(valuenumeric)
for point in (' + #cols + ')
) p '
exec sp_executesql #query,N'#startDate datetime, #endDate Datetime',#startDate,#endDate;

Related

Dynamic pivot in SQL : conversion failed

I have a table that date/time filed is nvarchar type when I create pivot table I get this error:
Msg 245, Level 16, State 1, Line 12
Conversion failed when converting the nvarchar value 'SELECT pr[آماده سازی],[فنی],[غیر فنی],[متفرقه],[CIP],[نامنطبق],[نت],[نظافت],[مواد اولیه] from
(
select stoptime,(prdname+convert(nvarchar,prsize))pr,stoptypetext
from Table_stop
where formnum in (select prdID from Table_production where prddate=iif(1398/06/04 is null,prddate,1398/06/04)
and prdgroup=iif(شب is null,prdgroup,شب) and idline=iif(' to data type int.
My code is:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#date NVARCHAR(10) = '1398/06/04',
#pgroup NVARCHAR(150) = N'شب',
#idline INT = 4
SELECT #cols = STUFF((SELECT ',' + QUOTENAME(stopTYPE)
FROM Table_stoptype
GROUP BY stopTYPE, stopid
ORDER BY stopid
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET #query = N'SELECT pr' + #cols + N' from
(
select stoptime,(prdname+convert(nvarchar,prsize))pr,stoptypetext
from Table_stop
where formnum in (select prdID from Table_production where prddate=iif('+#date+' is null,prddate,'+#date+')
and prdgroup=iif('+#pgroup+' is null,prdgroup,'+#pgroup+') and idline=iif('+#idline+' is null,idline,'+#idline+'))
) x
pivot
(
sum(stoptime)
for stoptypetext in (' + #cols + N')
) p '
EXEC sp_executesql #query;

Sql Pivoting on date

I am getting this error when trying to convert the below logic in to SQL query
Logic:
TRANSFORM First([SirName] & " - " & [SecondName]) AS Name
SELECT qry_Date.RoomNumber
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE (((qry_Date.RoomNumber) Is Not Null))
GROUP BY qry_Date.RoomNumber
PIVOT qry_Date.Date;
Below is what i have done so far
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(convert(NVARCHAR(MAX),qry_Date.Date,103))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT Name, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,qry_Date.Date
FROM Guest RIGHT JOIN qry_DateTemp ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)
Which results error
Msg 8114, Level 16, State 1, Line 9 Error converting data type
nvarchar to datetime2. Msg 473, Level 16, State 1, Line 9 The
incorrect value "13/12/2014" is supplied in the PIVOT operator. Msg
207, Level 16, State 1, Line 1 Invalid column name 'Name'.
My print #query output
SELECT Name, [01/12/2014],[02/12/2014],[03/12/2014],[04/12/2014],[05/12/2014],[06/12/2014],[07/12/2014],[08/12/2014],[09/12/2014],[10/12/2014],[11/12/2014],[12/12/2014],[13/12/2014],[14/12/2014],[15/12/2014],[16/12/2014],[17/12/2014],[18/12/2014],[19/12/2014],[20/12/2014],[21/12/2014],[22/12/2014],[23/12/2014],[24/12/2014],[25/12/2014],[26/12/2014],[27/12/2014],[28/12/2014],[29/12/2014],[30/12/2014],[31/12/2014]
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,qry_Date.Date
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( [01/12/2014],[02/12/2014],[03/12/2014],[04/12/2014],[05/12/2014],[06/12/2014],[07/12/2014],[08/12/2014],[09/12/2014],[10/12/2014],[11/12/2014],[12/12/2014],[13/12/2014],[14/12/2014],[15/12/2014],[16/12/2014],[17/12/2014],[18/12/2014],[19/12/2014],[20/12/2014],[21/12/2014],[22/12/2014],[23/12/2014],[24/12/2014],[25/12/2014],[26/12/2014],[27/12/2014],[28/12/2014],[29/12/2014],[30/12/2014],[31/12/2014])
) as p
One quick way to deal with this error is to convert all data to varchar(max) in same manner. After all dates will become header, so it should be string.
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(CAST(qry_Date.Date AS NVARCHAR(MAX)))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT RoomNumber, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Name
,qry_Date.RoomNumber
,CAST(qry_Date.Date AS NVARCHAR(MAX)) as [Date]
FROM Guest RIGHT JOIN qry_DateTemp ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(count(Name) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)
#DhruvJoshi did it as u Proposed and true i was in error. when i got my results i had to change the query to
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #query AS VARCHAR(MAX)
SELECT #cols = STUFF((SELECT distinct top 100 percent
',' + QUOTENAME(CAST(qry_Date.Date AS NVARCHAR(MAX)))
FROM qry_Date
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT RoomNumber, ' + #cols + '
FROM
(SELECT [SirName] + '' - '' + [SecondName] AS Names
,qry_Date.RoomNumber
,CAST(qry_Date.Date AS NVARCHAR(MAX)) as [Date]
FROM Guest RIGHT JOIN qry_Date ON Guest.ID = qry_Date.GuestID
WHERE qry_Date.RoomNumber Is Not Null) as t
PIVOT
(MAX([Names]) FOR [Date] IN( ' + #cols + ')
) as p'
print #query
execute(#query)

Conversion failed when converting date and/or time from character string SQL Server 2012

Pivoting a table using a stored procedure in SQL Server 2012, I get the error. I have provided the stored procedure code:
CREATE PROCEDURE [dbo].[sp_Report_SalesJournal]
(#fromDate DATETIME,
#toDate DATETIME,
#locationId INT)
AS
BEGIN
DECLARE #cols AS NVARCHAR(MAX) = '';
DECLARE #query AS NVARCHAR(MAX) = '';
SELECT #cols = #cols + QUOTENAME(AccountName) + ','
FROM
(SELECT DISTCINT AccountName
FROM vw_SalesJournal
) AS tmp
SELECT #cols = SUBSTRING(#cols, 0, LEN(#cols))
SET #query =
'SELECT * from
(
select InvoiceDate, TransactionNumber, CustomerName, Amount, AccountName from vw_SalesJournal Where (InvoiceDate BETWEEN convert(date,' + #fromDate + ',105) AND convert(date,' + #toDate + ',105)) OR LocationId=' + #locationId + '
) src
pivot
(
max(Amount) for AccountName in (' + #cols + ')
) piv'
I have already gone through and also tried some of the answers provided on similar post.
you need to convert your date to string (with format YYYYMMDD) and enclose the date string in single quote before concatenate
BETWEEN ''' + convert(varchar(10), #fromDate, 121) + ''' AND

Pivot Rows to Columns Dynamically - SQL

/****** Script for SelectTopNRows command from SSMS ******/
declare #ActivityYear int = 2014
declare #ActivityYear1 int = 2015
declare #ActivityMonth int = 1
declare #ActivityMonth1 int = 3
Select FinancialCategory, ID, (CONVERT(varchar(5), ActivityMonth) + '-'
+ CONVERT(varchar(5), ActivityYear)) As [Month-Year], Sum(HoursCharged) As [Hours]
FROM Forecast
where (ActivityMonth between #ActivityMonth and #ActivityMonth1)
AND (ActivityYear between #ActivityYear and #ActivityYear1)
AND FinancialCategory = 'Forecast'
Group By FinancialCategory, ID,ActivityMonth, ActivityYear
This Outputs a table that looks like this:
And I would like to transpose it to have the hours for each ID broken out by the dates in the range. Note: this range of dates will be dynamic, I set initial dates for testing purposes.
I learnt a bit about dynamic pivot recently, this post helped a lot. As a practice I converted yours, which I think would look like this, but isn't tested as I haven't time tcreate tables etc at the moment. HTH.
declare #ActivityYear int = 2014
declare #ActivityYear1 int = 2015
declare #ActivityMonth int = 1
declare #ActivityMonth1 int = 3
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME((CONVERT(varchar(5), ActivityMonth) + '-'
+ CONVERT(varchar(5), ActivityYear)))
FROM Forecast
WHERE (ActivityMonth between #ActivityMonth and #ActivityMonth1)
AND (ActivityYear between #ActivityYear and #ActivityYear1)
AND FinancialCategory = 'Forecast'
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FinancialCategory, ID, ' + #cols + ' FROM
(
SELECT FinancialCategory, ID, (CONVERT(varchar(5), ActivityMonth) + ''-''
+ CONVERT(varchar(5), ActivityYear)) As [Month-Year],HoursCharged
FROM Forecast
WHERE (ActivityMonth between ' + #ActivityMonth + ' and ' + #ActivityMonth1 + ')
AND (ActivityYear between ' + #ActivityYear + ' and ' +
#ActivityYear1 + ')
AND FinancialCategory = ''Forecast''
) x
PIVOT
(
Sum(HoursCharged)
for (CONVERT(varchar(5), ActivityMonth) + ''-''
+ CONVERT(varchar(5), ActivityYear)) in (' + #cols + ')
) p '
execute(#query)

Conversion failed when converting date and/or time from character string

I am struggling with this query which returns the error: Conversion failed when converting date and/or time from character string.
This is a common error judging from my google searches, but nothing I've tried so far works. I've tried casting #startdate as datetime and varchar and leaving it alone, as in the below example.
I've also tried using convert against the fieldname and the parameter name, although admittedly, I may just be getting the syntax wrong.
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int,
#startdate DATETIME
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname) from FormResponse WHERE FormID = #formid AND value IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse WHERE FormID = ' + CAST(#formid AS VARCHAR(25)) + ' AND createDate > ' + #startdate + '
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
edit: the query works except when I add the bit causing the error:
' AND createDate > ' + #startdate + '
The problem is you are attempting to concatenate a datetime to your varchar sql string. You need to convert it:
convert(varchar(10), #startdate, 120)
So the full code will be:
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int,
#startdate DATETIME
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname) from FormResponse WHERE FormID = #formid AND value IS NOT NULL FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT FormID, FormSubmissionID,' + #cols + ' from
(
SELECT FormID, FormSubmissionID, fieldname, value
FROM FormResponse
WHERE FormID = ' + CAST(#formid AS VARCHAR(25)) + '
AND createDate > ''' + convert(varchar(10), #startdate, 120) + '''
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
When you dynamically build the SQL Statement, the date value needs to be wrapped in single quotes. Whenever building a dynamic statement, do a SELECT #query and make sure the results look correct.
For your example, you would need to have 'WHERE createdate > ''' + covert(varchar(10), #startdate, 111) + '''
That would output: WHERE createdate > '2013/05/29'
Without the single quotes you would have: WHERE createdate > 2013/05/29