Pivot 时从字符串转换日期 and/or 时间时转换失败
Conversion failed when converting date and/or time from character string while Pivot
我有以下 SQL 查询:
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);
但是我收到这个错误:
Msg 241, Level 16, State 1, Line 16
Conversion failed when converting date and/or time from character string.
在与 string
连接之前,您需要明确地将 datetime
转换为 varchar
此外,您还需要在 datetime 参数周围附加两个单引号,以用单引号将日期括起来。
为了避免所有这些麻烦,我建议使用参数化 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;
问题不在这些行中,问题在动态 sql 部分,您将 datetime
数据类型 @startdate
和 @enddate
附加到字符串。应该是:
....
Timestamp between ''' +
CONVERT(NVARCHAR(50), @startDate, 121)+ ''' and ''' + CONVERT(NVARCHAR(50),@endDate, 121) + '''
) x
...
您还需要添加更多 '
以便将查询正确组合为动态 sql 查询。
因此您的完整查询将是:
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.
我有以下 SQL 查询:
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);
但是我收到这个错误:
Msg 241, Level 16, State 1, Line 16
Conversion failed when converting date and/or time from character string.
在与 string
datetime
转换为 varchar
此外,您还需要在 datetime 参数周围附加两个单引号,以用单引号将日期括起来。
为了避免所有这些麻烦,我建议使用参数化 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;
问题不在这些行中,问题在动态 sql 部分,您将 datetime
数据类型 @startdate
和 @enddate
附加到字符串。应该是:
....
Timestamp between ''' +
CONVERT(NVARCHAR(50), @startDate, 121)+ ''' and ''' + CONVERT(NVARCHAR(50),@endDate, 121) + '''
) x
...
您还需要添加更多 '
以便将查询正确组合为动态 sql 查询。
因此您的完整查询将是:
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.