sqlserver下通用 行转列 函数(原创)

摘要:
因为项目中经常需要行到列的统计报告,所以每次编写都需要花费大量的精力。今天,我们专门花了几个小时为Sqlserver编写了一组通用的行到列存储过程,它使用了sqlserver2000附带的pubs示例库。实验目标:在水平表中显示作者所写的图书价格,例如:作者的标题1标题2标题3标题4张三25.03.5李斯89.054.301˃第一,找出相应的书名和价格Sql语句如下:select.au_lname,c.titleas

因项目中常需要行转列的统计报表,每次编写时,均费一番功夫,今天特地花费几个小时编写了一套用于Sqlserver的 通用行转列 存储过程

采用sqlserver2000自带的pubs示例库,实验目标:

将作者所写的图书价格 以横向表格展示 如:

作者书名1书名2书名3书名4
张三25.03.5  
李四  89.054.30

1>首先查询出作者对应的书名以及价格

Sql语句如下

select a.au_lname,c.title as colName,cast(price as nvarchar(50)) as result
from authors a ,titleauthor b,titles c
where a.au_id = b.au_id and c.title_id= b.title_id
如图所示:

@YEZVR}Y@]`AXU{`A$)_E$G

2>只需将sql语句放入存储过程参数即可:

declare @temp nvarchar(500)
set @temp = 'select a.au_lname as 作者,c.title as colName,cast(price as nvarchar(50)) as result
from authors a ,titleauthor b,titles c
where a.au_id = b.au_id and c.title_id= b.title_id '
exec CommonRowToCol  @temp  

执行效果

QQ图片20131011182343

3>使用时,只需将要作为列名的字段定义为colname,将欲显示的列定义为result即可

完整的存储过程代码如下:

create procedure dbo.CommonRowToCol
    @sql nvarchar(4000)
as 
begin
--必须包含colname列和result列(不区分大小写),
--除colname列和result列 其余各列均会作为判别记录唯一性的条件
 
    create table #temp([序号] int IDENTITY(1,1)) 
    declare @sqlTemp nvarchar(4000),@sql_select nvarchar(1000),@temp nvarchar(500)
    declare @sql_All nvarchar(4000),@sql_Table nvarchar(1000),@sql_declare nvarchar(1000),@sql_Fetch nvarchar(1000) ,
            @sql_id nvarchar(1000),@sql_id2 nvarchar(1000),@sql_insert nvarchar(1000),@sql_value nvarchar(1000)
 
    set @sql_select = '' set @sql_All = '' set @sql_Table ='' set @sql_declare = '' set @sql_Fetch = ''
    set @sql_id = '' set @sql_id2 = '' set @sql_insert='' set @sql_value = ''
    
    set @sql = lower(LTRIM(@sql))
    set @sqlTemp = @sql
    set @sqlTemp = ' select top 0 * into #tempTbl from ('+@sqlTemp+')z '+
        ' select @temp =  Name+'',''+@temp from ( select top 1111 name from tempdb..syscolumns where id = object_id(N''tempdb..#tempTbl'') order by colorder )z '
    EXECUTE sp_executesql @sqlTemp, N'@temp nvarchar(1000) output',@sql_select output
 
    while charindex(',',@sql_select) > 0 
    begin
        select @temp = lower(LEFT(@sql_select,charindex(',',@sql_select)-1))
        select @sql_select = stuff(@sql_select,1,charindex(',',@sql_select),'')
        
        if (@temp <> 'colname') and (@temp<>'result')
        begin
            set @sql_Table = ' ['+@temp+'] nvarchar(1000),' + @sql_Table     
            set @sql_insert = ' ['+@temp+'],' + @sql_insert     
            set @sql_value ='isnull(@'+@temp+',''''),'+@sql_value 
            set @sql_id =  ' ['+@temp+'] =  isnull(@'+@temp+','''') and' + @sql_id
            set @sql_id2 = ' ['+@temp+'] =  isnull(''''''+@'+@temp+'+'''''' ,'''''''') and' + @sql_id2
        end;
        set @sql_declare = ' @'+@temp+' nvarchar(1000),'+@sql_declare 
        set @sql_Fetch = ' @'+@temp+','+@sql_Fetch 
    end;
    set @sql_Table = 'ALTER TABLE #temp ADD ' +left(@sql_Table,len(@sql_table)-1)+' '
    set @sql_declare = 'declare @sqlTemp nvarchar(4000),' +left(@sql_declare,len(@sql_declare)-1) + ' '
    set @sql_Fetch = left(@sql_Fetch,len(@sql_fetch)-1) + ' '
    set @sql_id = left(@sql_id,len(@sql_id)-3) + ' '
    set @sql_id2 = left(@sql_id2,len(@sql_id2)-3) + ' '
    set @sql_insert = left(@sql_insert,len(@sql_insert)-1) + ' '
    set @sql_value = left(@sql_value,len(@sql_value)-1) + ' '
 
    set @sql_All = @sql_declare + 
            ' Declare myCur Cursor   For '+ @sql + ' Open myCur Fetch NEXT From myCur Into '+ @sql_Fetch+
            ' While @@fetch_status=0 Begin '+
            '   if not exists(select * from tempdb..syscolumns where id = object_id(N''tempdb..#temp'') and name = @colName)
                begin            
                    set @sqlTemp =''alter table #temp add [''+@colName+''] nvarchar(4000) ''
                    exec(@sqlTemp)
                end 
                if not exists(select * from #temp where '+@sql_id+')
                begin
                    insert into #temp('+@sql_insert+') values('+@sql_value+')
                end 
                
                set @sqlTemp ='' update #temp set [''+@colName+''] = isnull(''''''+@result+'''''','''''''') where ' + @sql_id2+''' 
                exec(@sqlTemp)
                
                Fetch NEXT From myCur Into '+ @sql_Fetch+
            'end 
            Close myCur 
            Deallocate myCur 
            select * from #temp
            '
            
    exec (@sql_Table)
    exec(@sql_All)
end

4>以上代码在sqlserver2000,2005,2008测试通过.

5>交流请留言,转载请标注

免责声明:文章转载自《sqlserver下通用 行转列 函数(原创)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇windows系统下载地址大全&amp;amp;大白菜下载和教程存储过程,存储函数(Oracle)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[转载]oracle 存储过程的基本语法及注意事项

原文地址:oracle 存储过程的基本语法及注意事项作者:简单爱  oracle 存储过程的基本语法及注意事项 1.基本结构 CREATE OR REPLACE PROCEDURE 存储过程名字 (     参数1 IN NUMBER,     参数2 IN NUMBER ) IS 变量1 INTEGER :=0; 变量2 DATE; BEGIN...

sql server中:isnull(列名,0) 和isnull(列名,0)&amp;lt;&amp;gt;0 的区别

1、isnull(参数1,参数2),判断参数1是否为NULL,如果是,返回参数2,否则返回参数1。 2、isnull(列名,0),isnull()函数是用来判断列名是否为null,如果为NUll,则返回0,否则,返回列名的值。 3、<>:是不等号,与!=一样  比如select 3 where 1<>2 查出来的结果是3,selec...

MySQL存储过程之事务管理

  MySQL存储过程之事务管理 ACID:Atomic、Consistent、Isolated、Durable 存储程序提供了一个绝佳的机制来定义、封装和管理事务。 1,MySQL的事务支持 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关: Java代码 1         MyISAM:不支持事务,用于只读程序提高性能 ...

[置顶] 关于怎样提权的小帖子

牛逼版本 http://blog.csdn.net/eldn__/article/details/8452242 常见版本 http://www.jb51.net/hack/21297.html http://hi.baidu.com/happy8d/item/6839edc2ba343953ac00efcc http://www.webshell...

关于MSSQL导入导出时主键与约束丢失的问题解决

导入数据时,使用默认选项,会丢失主键、约束、默认值等属性,按如下步骤操作:-->导出向导 -->选择数据源 -->选择目的 -->指定表复制或查询:不要使用默认选项,选择“在SQL Server数据库之间复制对象和数据” -->选择要复制的对象:在本页中根据需要选择相应的开关项,对于列约束,必须选择“扩展属性”,若去掉“复制所...

Java NIO 学习笔记

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。 http://www.cnblogs.com/shijiaqi1066/p/3344148.html 0 概述 0.1 Socket的问题 传统socket由于需要等待资源,所以会出现阻塞现象。服务器端一般只能使用一个客户端socket对应一个处理线程。 但是...