sql大容量数据导出到Excel(单文件多sheet方法,适合数据不超过20万)

ContractedBlock.gif ExpandedBlockStart.gif Code
CREATE proc sqlToMultiExcelSheet
@sqlstr nvarchar(4000),    --查询语句,如果查询语句中使用了order by ,请加上top 100 percent  
@primaryKey varchar(100),--分页主键字段
@path nvarchar(1000),   --文件存放目录  
@fname nvarchar(250),   --文件名  
@sheetname varchar(250)=''  --要创建的工作表名,默认为文件名  
as   
set nocount on
declare @err int,@src nvarchar(255),@out int,@desc nvarchar(255),@sheetCount int,@i int,@topCount int,@where varchar(1000),@from varchar(1000),@myWhere varchar(1000),@filename varchar(250)
declare @obj int,@constr nvarchar(1000),@sql varchar(8000),@fdlist varchar(8000),@totalCount int,@pageCount int,@mySql varchar(8000)  

create table #pageTb(totalCount int)


set @from=substring(@sqlstr,charindex('from',@sqlstr)+5,len(@sqlstr)-charindex('from',@sqlstr)+1)

if charindex('where',@sqlstr)>0
 
set @where=substring(@sqlstr,charindex('where',@sqlstr)+6,len(@sqlstr)-charindex('where',@sqlstr)+1)
else
 
set @where=''


set @pageCount=65000
set @sql='select count(*) from ('+@sqlStr+') a'

insert into #pageTb execute (@sql)
select @totalCount=totalCount from #pageTb

--得出要导出的sheet数量
if @totalCount>@pageCount 
 
set @sheetCount=@totalCount/@pageCount+1
else
 
set @sheetCount=1

--参数检测  
if isnull(@fname,'')='' set @fname='temp.xls'  
if isnull(@sheetname,'')='' set @sheetname=replace(@fname,'.','#')  
  
--检查文件是否已经存在  
if right(@path,1)<>'\' set @path=@path+'\'  
create table #tb(a bit,b bit,c bit)  

  

--创建表的SQL  
declare @tbname sysname  
set @tbname='##tmp_'+convert(varchar(38),newid())  
set @sql='select top 1 * into ['+@tbname+'] from('+@sqlstr+') a'  
--print @sql  
exec(@sql)  
 

select @sql='',@fdlist=''  
select @fdlist=@fdlist+',['+a.name +']'
 ,
@sql=@sql+',['+a.name+''  
  
+case when b.name in('char','nchar','varchar','nvarchar'then  
     
'text('+cast(case when a.length>255 then 255 else a.length end as varchar)+')'  
   
when b.name in('tynyint','int','bigint','tinyint'then 'int'  
   
when b.name in('smalldatetime','datetime'then 'datetime'  
   
when b.name in('money','smallmoney'then 'money'  
   
else b.name end  
FROM tempdb..syscolumns a left join tempdb..systypes b on a.xtype=b.xusertype  
where b.name not in('image','text','uniqueidentifier','sql_variant','ntext','varbinary','binary','timestamp')  
 
and a.id=(select id from tempdb..sysobjects where name=@tbname)  

set @filename=@path+@fname  
truncate table #tb
insert into #tb exec master..xp_fileexist @filename

if exists(select 1 from #tb where a=1)  
 
set @constr='DRIVER={Microsoft Excel Driver (*.xls)};DSN='''';READONLY=FALSE;CREATE_DB="'+@filename+'";DBQ='+@filename
else  
  
set @constr='Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties="Excel 8.0;HDR=YES;DATABASE='+@filename+'"'   
  

--创建Excel文件
exec @err=sp_oacreate 'adodb.connection',@obj out  
if @err<>0 goto lberr  
  
exec @err=sp_oamethod @obj,'open',null,@constr  
if @err<>0 goto lberr    


set @i=1
while @i<=@sheetCount
begin 

 
--创建sheet语句
 set @mySql='create table ['+@sheetname+cast(@i as varchar)+']('+substring(@sql,2,8000)+')' 

 
 
--创建sheet 
 exec @err=sp_oamethod @obj,'execute',@out out,@mySql  
 
if @err<>0 goto lberr    
 
 
set @i=@i+1  
end

 
--关闭Excel
exec   @err=sp_oamethod   @obj,'close',null     
if   @err<>0   goto   lberr  
  
exec @err=sp_oadestroy @obj 


set @fdlist=substring(@fdlist,2,8000)  

set @i=1

--导入数据  
while @i<=@sheetCount
begin
 
set @topCount=(@i-1)*@pageCount 
  
 
set @sql='-1'
 
if @topCount<>0
 
begin
  
set @sql='select top '+cast(@topCount as varchar)+' '+@primaryKey+' from '+@from+' order by '+@primaryKey+' asc'
  
set @sql='select max('+@primaryKey+') from ('+@sql+') a'
 
end
 
 
if @where<>''
 
begin
  
set @myWhere=@primaryKey+' >('+@sql+') and '+@where
  
set @sql='select top '+convert(varchar,@pageCount)+' '+@fdlist+' from '+substring(@from,1,charindex('where',@from)-2)+' where '+@myWhere

 
end
 
else
 
begin
  
set @myWhere=@primaryKey+' >('+@sql+''
  
set @sql='select top '+convert(varchar,@pageCount)+' '+@fdlist+' from '+@from+' where '+@myWhere
 
end
 
 
set @constr='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=YES;DATABASE='+@filename+''',['+@sheetname+cast(@i as varchar)+'$])'

 
set ansi_nulls on
 
set ansi_warnings on
 
 
--print @sql
 execute('insert into '+@constr+'('+@fdlist+''+@sql)

 
set @i=@i+1
end

set @sql='drop table ['+@tbname+']'  
exec(@sql)  


set ansi_nulls off 
set ansi_warnings off

return  
  
lberr:  
 
exec sp_oageterrorinfo 0,@src out,@desc out  
lbexit:  
 
select cast(@err as varbinary(4)) as 错误号  
  ,
@src as 错误源,@desc as 错误描述  
 
select @sql,@constr,@fdlist
GO

转载于:https://www.cnblogs.com/xiaobier/archive/2009/05/19/1460241.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值