用如下过程即可,CREATE PROCEDURE P_CrossTab --交叉表生成器
@vSourceTAB As Varchar(200), --数据来源表,可以为表,视图,或者SQL语句(要用括号以及别名:如上注释段)
@vGroupbyField As Varchar(1000), --被selct Group By 要显示出来的,可以多个字段(记录可以有空值)
@vTransFormCol As Varchar(500), --交叉表中的合计等函数计算值的字段
@vFunction As Varchar(500)='Sum', --默认值,交叉表中的函数,也可以是' 2*Sum'的计算公式
@vPivotCol As Varchar(500), --要转换成列的字段,唯一列,可以是表达式'Field1+Field2'(记录可以有空值)
@vStrWhere As Varchar(1000)=null,--Where 约束条件,可以为空
@AggreGate as Varchar(1000)=null--聚集列,不会放到groupby里面
AS
Declare @StrSql As Varchar(8000) --//总的SQL语句
Declare @StrSql2 As Varchar(8000)--//怕varchar(8000)不够长,我就遇到超过8000的问题
Declare @StrSql3 As Varchar(8000)--//加长总SQL语句
Declare @StrSql4 As Varchar(8000)--//加长总SQL语句
Declare @StrSql5 As Varchar(8000)--//加长总SQL语句
Declare @StrSum As Varchar(650) --//列合计
Declare @pCols As Varchar(8000)
Declare @StrWhere As Varchar(1000)
IF Rtrim(Ltrim(IsNull(@vStrWhere,''))) <> ''
Begin
Set @StrWhere=' Where ' + @vStrWhere + ' '
End
Else
Set @StrWhere=''
Execute('Declare CursorCross Cursor For
Select Distinct ' + @vPivotCol + ' From ' +@vSourceTAB+' '+@StrWhere+' Order By ' + @vPivotCol + ' For Read only ')
Begin
Set Nocount On
Set @StrSql =' '
Set @StrSql2=' '
Set @StrSql3=' '
Set @StrSql4=' '
Set @StrSql5=' 'Open CursorCross
While (0=0)
Begin
Fetch Next From CursorCross Into @pCols
IF (@@Fetch_Status<>0) Break
IF @pCols Is Null --//不为空值,
Set @pCols='Null'
--为了防止新创建的列的标题名称,与@vGroupbyField中的字段重名,
--新创建的列的标题名称都增加前缀[@vGroupbyField.新创建的列的标题名称]
--因Sql长度限制Max=8000,由源数据控制字段值不能为Null,因此这里不再检验值是否为Null
if len(@StrSql)>6000 and len(@StrSql2)>6000 and len(@StrSql3)>6000 and len(@StrSql4)>6000 and len(@StrSql5)<6000
Set @StrSql5=@StrSql5+',' + @vFunction +
'(Case '+@vPivotCol+' When ' + ''''+@pCols+''''+ ' Then '+@vTransFormCol +' End) As'+'['+@pCols+']'
if len(@StrSql)>6000 and len(@StrSql2)>6000 and len(@StrSql3)>6000 and len(@StrSql4)<6000
Set @StrSql4=@StrSql4+',' + @vFunction +
'(Case '+@vPivotCol+' When ' + ''''+@pCols+''''+ ' Then '+@vTransFormCol +' End) As'+'['+@pCols+']'
if len(@StrSql)>6000 and len(@StrSql2)>6000 and len(@StrSql3)<6000
Set @StrSql3=@StrSql3+',' + @vFunction +
'(Case '+@vPivotCol+' When ' + ''''+@pCols+''''+ ' Then '+@vTransFormCol +' End) As'+'['+@pCols+']'
if len(@StrSql)>6000 and len(@StrSql2)<6000
Set @StrSql2=@StrSql2+',' + @vFunction +'(Case '+@vPivotCol+' When ' + ''''+@pCols+''''+ ' Then '+@vTransFormCol +' End) As'+'['+@pCols+']'
if len(@StrSql)<6000
Set @StrSql=@StrSql +',' + @vFunction +'(Case '+@vPivotCol+' When ' + ''''+@pCols+''''+ ' Then '+@vTransFormCol +' End) As'+'['+@pCols+']'End
Close CursorCross
Deallocate CursorCross-- print ('Select '+@vGroupByField+' '+@StrSql2)+@StrSql+' From '+@vSourceTAB+' '+@StrWhere+' Group By '+@vGroupByField)
--print @strsql3if @AggreGate is null
Execute(' Select '+@vGroupByField+' '+@StrSql+@StrSql2+@StrSql3+@StrSql4+@StrSql5+' From '+@vSourceTAB+' '+@StrWhere+' Group By '+@vGroupByField)
else
Execute(' Select '+@vGroupByField+','+@AggreGate+' '+@StrSql+@StrSql2+@StrSql3+@StrSql4+@StrSql5+' From '+@vSourceTAB+' '+@StrWhere+' Group By '+@vGroupByField)IF @@Error <>0
Return @@Error
Return 0
End