【问题标题】:Conversion failed when converting date and/or time from character string while Pivot在 Pivot 时从字符串转换日期和/或时间时转换失败
【发布时间】:2017-12-25 11:55:04
【问题描述】:

我有以下 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);

但我收到此错误:

消息 241,第 16 级,状态 1,第 16 行
从字符串转换日期和/或时间时转换失败。

【问题讨论】:

    标签: sql sql-server pivot dynamic-sql


    【解决方案1】:

    问题不在于这些行,而在于动态 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);
    

    【讨论】:

    • 非常感谢。现在正在工作。唯一的问题是“时间戳”不按顺序排列。
    【解决方案2】:

    在与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;
    

    【讨论】:

    • 非常感谢。现在正在工作。唯一的问题是“时间戳”不按顺序排列。
    • @Pரதீப் 非常感谢。我到底需要在哪里“按时间戳添加订单”?
    • @Learner ..) p Order by timestamp'
    猜你喜欢
    • 2012-04-17
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多