怎么把一个表的行列转换?需要一个通用的存储过程!

n个列m个行的表
变为
m个列n个行的表

需要一个通用的存储过程!

---------------------------------------------------------------
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

/*--行列互换的通用存储过程

将指定的表,按指定的字段进行行列互换

--邹建 2004.04--*/

/*--使用示例

--测试数据
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

/*--要求转换结果
性别 小说 散文 哲学
---- ----- ----- -----
男性 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+''''''''
-- ,@s2=@s2+',@'+@i+'=''性别='''''+name+''''''''
,@s3=@s3+'
select @'+@i+'=@'+@i+'+'',[''+['+@fdname+']+'']=''+cast(['+name+'] as varchar) 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

select @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

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus