0

This executes correctly: (It is weird that I needed to use '' by the date for it to actually execute)

DECLARE 
@cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) FROM [85137_PHY_Long_PG] c FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')

set @query = 'SELECT statdate, ' + @cols + ' from 
        (
            select statdate, statcolumnname, statcolumnvalue
            from [85137_PHY_Long_PG]
       ) x
        pivot 
        (
             min(statcolumnvalue)
            for statcolumnname in (' + @cols + ')
        ) p WHERE statdate BETWEEN ''2012-04-01 12:15:00'' AND ''2012-04-01 12:45:00''      ORDER BY statdate'

execute(@query)

Now I want to replace the dates with variables:

DECLARE 
@cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX),
@from  AS NVARCHAR(MAX),
@to  AS NVARCHAR(MAX);

set @from = '2012-04-01 12:15:00'
set @to = '2012-04-01 12:45:00'

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) FROM [85137_PHY_Long_PG] c FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')

set @query = 'SELECT statdate, ' + @cols + ' from 
        (
            select statdate, statcolumnname, statcolumnvalue
            from [85137_PHY_Long_PG]
       ) x
        pivot 
        (
             min(statcolumnvalue)
            for statcolumnname in (' + @cols + ')
        ) p WHERE statdate BETWEEN ''+@from+'' AND ''+@to+'' ORDER BY statdate'

execute(@query)

I get the following error:Conversion failed when converting character string to smalldatetime data type

Changing the where statement to the following:

WHERE statdate BETWEEN ''+convert(smalldatetime,@from)+'' AND ''+convert(smalldatetime,@to)+'' ORDER BY statdate'

Still gives me the same error, just can't seem to replace the dates as variables

4

2 回答 2

1

'' 并不奇怪;它是一种在 varchars 中启用撇号的符号。

连接时,请确保您没有尝试连接 (n)varchars 和 (n)chars 以外的任何内容,因为 Sql Server 会尝试将它们转换为其他数据类型;在您的情况下,在 smalldatetime 中。您可以通过在连接之前/期间将参数日期显式转换为 nvarchars 来避免此麻烦,但更好的解决方案是使用sp_executesql和参数。

如果您在查询中保留参数:

set @query = 'SELECT statdate, ' + @cols + ' from 
    (
        select statdate, statcolumnname, statcolumnvalue
        from [85137_PHY_Long_PG]
   ) x
    pivot 
    (
         min(statcolumnvalue)
        for statcolumnname in (' + @cols + ')
    ) p WHERE statdate BETWEEN @from AND @to ORDER BY statdate'

您可以使用参数执行它:

exec sp_executesql @query, N'@from datetime, @to datetime', @from=@from_variable, @to=@to_variable

其中@from_variable 和@to_variable 是前面批量定义的日期时间变量。

更新:

如果您的最终目标是将此代码包装在存储过程中,这里有一个模板:

create proc MyProc (@dateFrom smalldatetime, @dateTo smalldatetime)
as
DECLARE 
@cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) 
  FROM [85137_PHY_Long_PG] c 
   FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set @query = 'SELECT statdate, ' + @cols + ' from 
    (
        select statdate, statcolumnname, statcolumnvalue
        from [85137_PHY_Long_PG]
   ) x
    pivot 
    (
         min(statcolumnvalue)
        for statcolumnname in (' + @cols + ')
    ) p WHERE statdate BETWEEN @from AND @to ORDER BY statdate'

exec sp_executesql @query, N'@from smalldatetime, @to smalldatetime', @from=@dateFrom, @to=@dateTo
于 2012-05-28T12:36:07.013 回答
0

特此解决:

DECLARE 
@cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX),
@internal_fromdate  AS SMALLDATETIME,
@internal_todate  AS SMALLDATETIME;

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) FROM [85137_PHY_Long_PG] c FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')

set @internal_fromdate = '2012-04-01 12:15:00';
set @internal_todate = '2012-04-01 12:45:00';

set @query = 'SELECT statdate, ' + @cols + ' from 
        (
            select statdate, statcolumnname, statcolumnvalue
            from [85137_PHY_Long_PG]
       ) x
        pivot 
        (
             min(statcolumnvalue)
            for statcolumnname in (' + @cols + ')
        ) p  WHERE statdate BETWEEN @FromDate AND @ToDate ORDER BY statdate'

exec sp_executesql @query, N'@FromDate SMALLDATETIME, @ToDate SMALLDATETIME', @FromDate=@internal_fromdate, @ToDate=@internal_todate

更新

好的,我尝试了以下变体:

create proc MyProc9 (@tableName varchar,@dateFrom smalldatetime, @dateTo smalldatetime)
AS
DECLARE 
@cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.statcolumnname) 
FROM [85137_PHY_Long_MP] c 
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
set @query = 'SELECT statdate, ' + @cols + ' from 
(
    SELECT statdate, statcolumnname, statcolumnvalue
    from @table
) x
pivot 
(
     min(statcolumnvalue)
    for statcolumnname in (' + @cols + ')
) p WHERE statdate BETWEEN @from AND @to ORDER BY statdate'

exec sp_executesql @query, N'@table varchar,@from smalldatetime, @to smalldatetime', @table=@tableName,@from=@dateFrom, @to=@dateTo

错误:必须声明表变量“@table”。

在@query 字符串中尝试了“+@tableName+”:“8”附近的语法不正确。

在@query 字符串中尝试了“+QUOTENAME(@tableName)+”:无效的对象名称“8”。

在@query 字符串中尝试了 ['+@tableName+']:无效的对象名称“8”。

在@query 字符串中尝试了 QUOTENAME(@table):无效的对象名称“8”。

在@query 字符串中尝试了 [85137_PHY_Long_MP]:工作正常,只是想替换它。

在 @query 字符串中尝试了 [@tableName]:无效的对象名称“@tableName”。

在@query 字符串中尝试了@tableName:必须声明表变量“@tableName”。

我不明白如何解决问题

于 2012-05-28T13:07:29.537 回答