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

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

Related

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

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

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;

Error converting data type varchar to numeric dynamic pivot

I am getting an error described in the title where my code looks like this:
declare
#cols numeric(10,0),
#sql numeric(10,0)
select #cols = isnull(#cols + ', ', '') + '[' + T.AmountPayd + ']' from (select distinct AmountPayd from t1) as T
select #sql = '
select *
from t1 as T
pivot
(
sum(T.AmountPayd) for T.Customer in (' + #cols + ')
) as P'
exec sp_executesql #sql = #sql
The error occurs at this line:
select #cols = isnull(#cols + ', ', '') + '[' + T.AmountPayd + ']' from (select distinct AmountPayd from t1) as T
In my table AmountPayd is declared as numeric data type.
The error I get is:
Msg 8114, Level 16, State 5, Line 108 Error converting data type
varchar to numeric.
You've declared #cols as numeric(10,0), but you're trying to assign text to it.
Probably need to declare it as nvarchar(max).
P.s.
by concatenating AmountPayd you're suppose to get a list of customers?
declare
--#cols numeric(10,0),
--#sql numeric(10,0)
#cols varchar(max),
#sql varchar(max)
--Here you are setting #cols to a concatenated list of the amounts in your table
--The problem is you are trying to concat a decimal or integer into a string without casting it
--This is the same as doing 'A' + 1 and wanting to get A1. You first have to cast it.
--Notice the CAST(T.AmountPayd AS VARCHAR). But cols still needs to be a varchar in your declaration.
select #cols = isnull(#cols + ', ', '') + '[' + CAST(T.AmountPayd AS VARCHAR) + ']' from (select distinct AmountPayd from t1) as T
--Here you are building your dynamic SQL, which is a string which is why #sql must be varchar or nvarchar
select #sql = '
select *
from t1 as T
pivot
(
sum(T.AmountPayd) for T.Customer in (' + #cols + ')
) as P'
exec sp_executesql #sql = #sql
You've almost copied this example line for line, you just missed the declaration of your variables.
http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/

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)

Dynamic Pivot Query with parameter

In the following query, the formid parameter is causing an error. I have tried using a static value in place of the formid parameter, in which case the query succeeds. Am I using improper syntax? This thread appear to solve the issue, but the syntax seems to be the same.
ALTER PROCEDURE [dbo].[customFormReport]
(
#formid int
)
AS
BEGIN
SET NOCOUNT ON
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(fieldname)
from FormResponse
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 = ' + #formid + '
) x
pivot
(
max(value)
for fieldname in (' + #cols + ')
) p '
execute(#query)
convert it to string,
CAST(#formid AS VARCHAR(25))