Create PROCEDURE CrossTable --交叉表生成器
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ--(Select Distinct SuppCode As SCode,MCode,PurQtyRate As Rate
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ-- From MtSPM A Inner Join MtSPD B On A.ID=B.MtSuppPriceM_ID
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ-- Inner Join Suppliers C On A.Supp_ID=C.ID
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ-- Where A.Active_KID=120 And AduitPass=1) D
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vSourceTAB As Varchar(2000), --数据来源表,可以为表,视图,或者SQL语句(要用括号以及别名:如上注释段)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vGroupbyField As Varchar(100), --被selct Group By 要显示出来的,可以多个字段(记录可以有空值)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vTransFormCol As Varchar(50), --交叉表中的合计等函数计算值的字段
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vFunction As Varchar(100)=' Sum', --默认值,交叉表中的函数,也可以是' 2*Sum'的计算公式
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vPivotCol As Varchar(100), --要转换成列的字段,唯一列,可以是表达式'Field1+Field2'(记录可以有空值)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vStrWhere As Varchar(1000) =Null, --Where 约束条件,可以为空
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ@vGroupbyFieldName As Varchar(50)=null --如果GroupField是表达式,则这里一定要指定名称,不然会出错
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈAS
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ--重要提示

StrSql的Largest size allowed Is 8000,因此尽量将少的字段内容转换为列
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈDeclare @StrSql As Varchar(8000) --//总的SQL语句
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈDeclare @StrSum As Varchar(3000) --//列合计
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈDeclare @pCols As Varchar(100)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈDeclare @StrWhere As Varchar(500)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈif @vGroupbyFieldName is null
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈset @vGroupbyFieldName=@vGroupbyField
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈset @strsql=' Declare CursorCross Cursor For
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ Select Distinct ' + @vPivotCol + ' From '
+@vSourceTAB +' Order By ' + @vPivotCol + ' For Read only '
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈPrint @StrSql
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈExecute(@StrSql)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈBegin
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet Nocount On
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @StrSql =''
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @StrSum=''
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @pCols=''
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈIF Rtrim(Ltrim(IsNull(@vStrWhere,''))) <> ''
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈBegin
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ Set @StrWhere=' Where ' + @vStrWhere + ' '
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈEnd
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈElse
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @StrWhere=''
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈOpen CursorCross
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈWhile (0=0)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈBegin
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ Fetch Next From CursorCross Into @pCols
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ IF (@@Fetch_Status<>0) Break
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ IF @pCols Is Null --//不为空值,
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ Set @pCols='Null'
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ --为了防止新创建的列的标题名称,与@vGroupbyField中的字段重名,
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ --新创建的列的标题名称都增加前缀[@vGroupbyField.新创建的列的标题名称]
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ--因Sql长度限制Max=8000,由源数据控制字段值不能为Null,因此这里不再检验值是否为Null
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ Set @StrSql=@StrSql +',' + @vFunction +
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ '(Case
'+@vPivotCol+' When ''' + @pCols+ ''' Then
'+@vTransFormCol +' Else Null End) As '+
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ '['+/*Left(@vPivotCol,1)+*/@pCols+']'
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ--因长度限制,不计算列间之和
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ-- Set @StrSum=@StrSum + '+IsNull(A.' + '['+Left(@vPivotCol,1)+@pCols+']' +',0)'
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈEnd
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @StrSql = ' Select ' + @vGroupByField +' AS
'+@vGroupbyFieldName+ ' '
+@StrSql + ' From '
+@vSourceTAB+ ' ' + @StrWhere +
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ ' Group By ' + @vGroupByField
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ--列向合计 为字段名'TotalSum',合计方法改为重新从源表中取值,减少SQL的字符量
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @StrSql ='Select A.*,(select '+
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ @vFunction+'('
+@vTransFormCol +') from '+ @vSourceTAB+@StrWhere+' Group by
'+@vGroupbyField+ ' having
'+@vGroupbyField+'=A.'+@vGroupbyFieldName+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ +') As TotalSum From (' + @StrSql +') As A'
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈSet @StrSql ='Select A.* From (
'+@StrSql+') As A Order By
'+@vGroupByFieldName+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈPrint @StrSql
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈExecute(@StrSql)
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈIF @@Error <>0
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ Return @@Error
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈClose CursorCross
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈDeallocate CursorCross
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈReturn 0
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈEnd
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈgo
+y¼*ø/ãbbs.51ecom.ccÈê©é[þxÈ