我调试以下行列调换的列的时候会出现报错,不知道怎么改了,请各位高手帮个忙。报错是这样的:
服务器: 消息 156,级别 15,状态 1,行 2
在关键字 'select' 附近有语法错误。
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_zj]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_zj]
GO/*--使用示例 --测试数据
 create table 表(类别 varchar(10),男性 decimal(20,1),女性 decimal(20,1))
 insert 表 select '小说',38.0,59.2
 union all select '散文',18.9,30.6
 union all select '哲学',16.2,10.2
        select * from 表
 /*--要求转换结果
  性别   小说    散文    哲学    
  ---- ----- ----- ----- 
  男性   38.0  18.9  16.2
  女性   59.2  30.6  10.2
  
  (所影响的行数为 2 行)
 --*/ --调用存储过程
 exec p_zj '表','类别','性别' --删除测试
 drop table 表
--*/
create proc p_zj
@tbname sysname,  --要处理的表名
@fdname sysname,  --做为转换的列名
@new_fdname sysname='' --为转换后的列指定列名
as
declare @s1 varchar(8000),@s2 varchar(8000)
 ,@s3 varchar(8000),@s4 varchar(8000),@s5 varchar(8000)
 ,@i varchar(10)
select @s1='',@s2='',@s3='',@s4='',@s5='',@i='0'
select @s1=@s1+',@'+@i+' varchar(8000)'
 ,@s2=@s2+',@'+@i+'='''+case isnull(@new_fdname,'') when '' then ''
  else @new_fdname+'=' end+''''''+name+''''''''
 ,@s3=@s3+'
select @'+@i+'=@'+@i+'+'',[''+cast(['+@fdname+'] as varchar)+'']=''''''+replace(['+name+'],'''','''''''')+'''''''' from ['+@tbname+']'
 ,@s4=@s4+',@'+@i+'=''select ''+@'+@i
 ,@s5=@s5+'+'' union all ''+@'+@i
 ,@i=cast(@i as int)+1
from syscolumns 
where object_id(@tbname)=id and name<>@fdname
order by colidselect @s1=substring(@s1,2,8000)
 ,@s2=substring(@s2,2,8000)
 ,@s4=substring(@s4,2,8000)
 ,@s5=substring(@s5,16,8000)exec('declare '+@s1+'
select '+@s2+@s3+'
select '+@s4+'
exec('+@s5+')')
go

解决方案 »

  1.   

    我调试过了报错基本是在执行
    exec('declare '+@s1+'
    select '+@s2+@s3+'
    select '+@s4+'
    exec('+@s5+')')
    这个部分的时候出现的。
      

  2.   

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_zj]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_zj]
    GO
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[表]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[表]
    GO
     --测试数据
     create table 表(类别 Nvarchar(10),男性 decimal(20,1),女性 decimal(20,1))
     insert 表 select N'小说',38.0,59.2
     union all select N'散文',18.9,30.6
     union all select N'哲学',16.2,10.2
    GO
    create proc p_zj
    @tbname sysname,  --要处理的表名
    @fdname sysname,  --做为转换的列名
    @new_fdname sysname='' --为转换后的列指定列名
    as
    declare @s1 Nvarchar(4000),@s2 Nvarchar(4000)
     ,@s3 Nvarchar(4000),@s4 Nvarchar(4000),@s5 Nvarchar(4000)
     ,@i varchar(10)
    select @s1='',@s2='',@s3='',@s4='',@s5='',@i='0'
    select @s1=@s1+',@'+@i+' Nvarchar(4000)'
     ,@s2=@s2+',@'+@i+'=N'''+case isnull(@new_fdname,'') when '' then ''
      else @new_fdname+'=' end+''''''+name+''''''''
     ,@s3=@s3+'
    select @'+@i+'=@'+@i+'+'',[''+cast(['+@fdname+'] as Nvarchar)+'']=N''''''+replace(['+name+'],'''','''''''')+'''''''' from ['+@tbname+']'
     ,@s4=@s4+',@'+@i+'=''select ''+@'+@i
     ,@s5=@s5+'+'' union all ''+@'+@i
     ,@i=cast(@i as int)+1
    from syscolumns 
    where object_id(@tbname)=id and name<>@fdname
    order by colidselect @s1=substring(@s1,2,4000)
     ,@s2=substring(@s2,2,4000)
     ,@s4=substring(@s4,2,4000)
     ,@s5=substring(@s5,16,4000)exec('declare '+@s1+'
    select '+@s2+@s3+'
    select '+@s4+'
    exec('+@s5+')')
    go
     --调用存储过程
     exec p_zj N'表',N'类别',N'性别' --删除测试
     drop table 表
    --這個沒錯誤
      

  3.   

    还有忘了说了,@tbname(要处理的表名)是一个全局临时表,报错是不是跟这个有关系呢?