1

I have a stored procedure for pivoting manually

ALTER procedure [dbo].[performancepivot] (
    @startdate datetime, 
    @enddate datetime
) as begin

    set nocount on
    declare @date1 nvarchar(100)=convert(varchar, @startdate+'00:00:00.000',120),
            @date2 nvarchar(100)= convert(varchar, @enddate+'23:59:59.000',120);

    with cte as 
          dbo.testfunctionstacknew(convert(decimal(10,1),avg(convert(numeric(18,2), datediff(ss, t.Paydate, t.DelDate))))) as Average
        from Transaction_tbl as t
            left join VType_tbl as v on t.vtid = v.vtid
            left join Location_tbl as l on t.Locid = l.Locid
        where t.Locid in (select t1.Locid from Transaction_tbl as t1)
          and t.dtime between @date1 and @date2
          and t.Status = 5
        group by v.Vtype, l.LocName, l.Locid)

    select c.LocName, 
        max(case when c.Vtype = 'Normal' then Average end) as Normal,
        max(case when c.Vtype = 'Vip' then Average end) as Vip,
        max(case when c.Vtype = 'VVip'   then Average end) as VVip,   
        max(case when c.Vtype = 'Pass' then Average end) as Pass,
        max(case when c.Vtype = 'Staff' then Average end) as Staff  
    from cte as c group by c.LocName order by c.LocName
end

while executing this i am getting exact out put..i dont want pivot manually..so i try to write stored procedure 'pivot Dynamically'.. i try to write stored procedure like this:

ALTER procedure [dbo].[ParkingSummary1]
     @startdate nvarchar(100), @enddate nvarchar(100) as
    begin 
      declare @date1 nvarchar(100) = convert(varchar, @startdate+' 00:00:00.000', 120)
      declare @date2 nvarchar(100) = convert(varchar, @enddate+' 23:59:59.000', 120)
      DECLARE @cols AS NVARCHAR(MAX),@query  AS NVARCHAR(MAX)
      select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype) from VType_tbl
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')  ,1,1,'')
      set @query = 'SELECT LocName, ' + @cols + '(  
      select l.LocName,v.Vtype,[dbo].[testfunctionstacknew](
      CONVERT(decimal(10,1), AVG( CONVERT(NUMERIC(18,2),
      DATEDIFF(SS,t.Paydate,t.DelDate) ) ))) as Average  
     from (select l.LocName,Vtype from   Transaction_tbl t join
      VType_tbl v on t.vtid = v.vtid join dbo.Location_tbl l on 
      t.locid=l.Locid  where dtime between '''+ @date1 +''' and '''+ @date2 +'''  
      and Status = 5) d  pivot  ( count(Vtype) for Vtype in (' + @cols + ')) p '
      print @query
     exec sp_executesql @query;
      end

but while executing this stored procedure i am getting error:Column 'Location_tbl.LocName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. what is wrong with my second stored procedure..if any one know please help me to find out

4

1 回答 1

0

您需要在@query 中执行命令。“print @query”只输出命令本身。对调试很有用,所以只需注释掉那一行..

在打印命令下插入:

exec sp_executesql @query;

更多关于 sp_executesql 的信息: http ://technet.microsoft.com/en-us/library/ms175170(v=sql.105).aspx

编辑:

您生成的查询包含错误。也没有必要将日期时间转换为 varchars 来完成你想要的。这应该解决这两个问题(注意,盲编码,@query 仅在语法上正确)

alter procedure [dbo].[ParkingSummary1] (
     @startdate datetime
     , @enddate datetime )
     as
    begin
      DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX)
      declare @params nvarchar(50) = '@date1 datetime, @date2 datetime';
      declare @date1 datetime = dateadd(day, datediff(day, 0, @startdate), 0);
      declare @date2 datetime = dateadd(day, datediff(day, 0, @enddate) + 1, 0);

      select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Vtype) from VType_tbl
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')  ,1,1,'')

      set @query = 'SELECT LocName, ' + @cols + '
      from 
      (
        select l.LocName, Vtype, [dbo].[testfunctionstacknew](
            CONVERT(decimal(10,1), AVG( CONVERT(NUMERIC(18,2),
            DATEDIFF(SS,t.Paydate,t.DelDate) ) ))) as Average 
        from Transaction_tbl t 
        join VType_tbl v on t.vtid = v.vtid 
        join dbo.Location_tbl l on t.locid=l.Locid 
        where dtime >= @date1 and dtime < @date2
        and Status = 5
        group by l.LocName, VType
       ) d 
       pivot ( max(Average) for Vtype in (' + @cols + ')) p '
    print @query;
    --pass date1 and date2 as datetime parameters, not varchars.
    exec sp_executesql @query, @params, @date1, @date2
end

记得打印要调试的变量。另请查看 sp_executesql 网站以获取有关 @query、@params、@date1、@date2 语法的说明。

于 2013-09-17T10:10:33.470 回答