首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > asp.net >

紧急SQL2005存储过程导出EXCEL打不开

2012-12-22 
紧急求救!SQL2005存储过程导出EXCEL打不开。我的存储过程如下现在的问题是执行存储过程是成功的,但导出的EX

紧急求救!SQL2005存储过程导出EXCEL打不开。
我的存储过程如下现在的问题是执行存储过程是成功的,但导出的EXCEL只有6KB,而且打不开,删也删不掉。
我机器上装了OFFICE2007,VS2008SP1。喜欢各位大侠帮帮忙,项目急用。而这个机器在公司部分的机器上是成功的,在server2003上是成功的。
GO
/****** 对象:  StoredProcedure [dbo].[H_SqlToExcel]    脚本日期: 03/23/2010 17:25:57 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
    
  ALTER   PROC   [dbo].[H_SqlToExcel]   
  (   
  @Path                   varchar(100),--文件存放路径   
  @Fname                 varchar(100),--文件名字   
  @SheetName         varchar(80),---工作表名字   
  @SqlStr               varchar(8000)--查询语句,如果查询语句中使用了order       by       ,请加上top       100       percent,注意,如果导出表/视图,用上面的存储过程       
  /*
  exec H_SqlToExcel 'c:\','test2.xls','sheet1','SELECT TOP 10 PersonName FROM PersonalBaseInfo' 
  */
  )   
  AS   
  SET   NOCOUNT   ON   
    
  declare     @sql                 varchar(8000)   
  declare     @obj                 int--OLE对象   
  declare     @constr           varchar(8000)   
  declare     @err                 int   
  declare     @out                 int   
  declare     @fdlist           varchar(8000)   
  declare     @tbname           sysname--临时表   
  declare     @Src                 nvarchar(200)   
  declare     @Desc               nvarchar(200)   
    
  set   @tbname='##tmp_'+convert(varchar(38),newid())   
    
  exec('select   *   into   ['+@tbname   +']   from   '+'('+@sqlStr+')   A')   
    
  select   @fdlist   =   ''   
    
  set   @sql=   @path+@fname   


    set   @constr='DRIVER={Microsoft Excel Driver (*.xls)};DSN='''';READONLY=FALSE'   
                +';CREATE_DB="'+@sql+'";DBQ='+@sql   
    
  --生成Excel的列   
  set   @sql   =   ''   
  select   @sql   =   @sql+','+'['+a.name+']   '+   case   when   b.name   like   '%char'   then   case   when   a.length   >255   then   'memo'   else   'text('+cast(a.length   as   varchar)+')'   end   
                            when   b.name   like   '%int'   or   b.name='bit'   then   'int'   
            when   b.name   like   '%datetime'   then   'datetime'   
                  when   b.name   like   '%money'   then   'money'   
                                                                                            when   b.name   like   '%text'   then   'memo'   
            else   b.name   
                end,       
  @fdlist   =   @fdlist+','+'['+a.name+']'     
  from   tempdb..syscolumns   a     join   tempdb..systypes   b   on   a.xtype   =   b.xusertype     
  where   b.name   not   in('image','uniqueidentifier','sql_variant','varbinary','binary','timestamp')     
              and   id   in(select   id   from   tempdb..sysobjects   where   name   =   @tbname)   order   by   colorder   
  if   @@rowcount=0   return   
    
  set   @fdlist   =   substring(@fdlist,2,8000)   


    
  --连接数据库   
  exec   @err=sp_oacreate   'adodb.connection',@obj   out   
  if   @err   <>   0     goto   lberror   
  exec   @err=sp_oamethod   @obj,'open',null,@constr   
  if   @err   <>   0     goto   lberror   
  --创建工作薄   
  select   @sql='create   table   ['+@sheetname   
    +']('+substring(@sql,2,8000)+')'   
    
  exec   @err=sp_oamethod   @obj,'execute',@out   out,@sql--@sql为excute方法提供参数   
    
  if   @err   <>   0     goto   lberror   
    
  exec   @err=sp_oadestroy   @obj   
    
  --导入数据   
  set   @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=YES   
        ;DATABASE='+@path+@fname+''',['+@sheetname+'$])'   
  --print   @sql   
  exec   ('insert   into   '+@sql+'('+@fdlist+')   select   '+@fdlist+'   from   ['+@tbname+']')   
    
  exec('drop   table   ['+@tbname+']')   
  return   
    
    
  lberror:   
    exec   sp_oageterrorinfo   0,@src   out,@desc   out   
    
  lbexit:   
    select   cast(@err   as   varbinary(4))   as   错误号   
      ,@src   as   错误源,@desc   as   错误描述   
    select   @sql,@constr,@fdlist   
    
    

[最优解释]
建议使用clr存储过程

http://blog.csdn.net/jinjazz/archive/2009/04/29/4138000.aspx
[其他解释]
哇。。。太长了。只有时间顶,没有时间看。
[其他解释]
如果关不掉说明进程中还执行EXCEL的进程。

开启'Ole Automation Procedures'的服务

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO

EXEC sp_configure 'Ole Automation Procedures';
GO


exec H_SqlToExcel 'c:\','test2.xls','sheet1','SELECT TOP 10 PersonName FROM PersonalBaseInfo' 
红色的你详细看一下

我机器 sql2005 office2003 执行没有问题
------其他解决方案--------------------


对 我找了一个只装过哦OFFICE2003的 执行就没有问题

[其他解释]
看来是环境配置问题了。

可能2008有其它的设置吧。
因环境而议了。祝LZ好运
[其他解释]
谁能帮助我啊? 3楼说的那个可能解释下!
[其他解释]
我在2007的上边执行也不行。

select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\2007.xlsx', 'select * from [Sheet1$]')   

set @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=YES 
;DATABASE='+@path+@fname+''',['+@sheetname+'$])' 

2007不能再使用''MICROSOFT.JET.OLEDB.4.0''
你更改成'Microsoft.ACE.OLEDB.12.0' 试下
[其他解释]
在公司部分的机器上是成功的...

-----------------------------------------------

环境配置问题,可以换个方法。
[其他解释]
请大家帮忙!
[其他解释]

引用:
建议使用clr存储过程

http://blog.csdn.net/jinjazz/archive/2009/04/29/4138000.aspx


那边得执行也有问题 请问你有源码吗!
[其他解释]
选个别几个指定的字段没有问题,用"*"全部字段就报错。
[其他解释]

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_exporttb]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) 
drop procedure [dbo].[p_exporttb] 
GO 

/*--数据导出EXCEL
 
 导出查询中的数据到Excel,包含字段名,文件为真正的Excel文件
 如果文件不存在,将自动创建文件
 如果表不存在,将自动创建表
 基于通用性考虑,仅支持导出标准数据类型

--邹建 2003.10(引用请保留此信息)--
增加分页功能
.5w条一页
--Add by 谢小漫--
*/

/*--调用示例

 p_exporttb @sqlstr='select * from spkfk'
  ,@path='c:\',@fname='spkfk.xls',@sheetname='商品资料'

--*/
CREATE        proc p_exporttb
@sqlstr varchar(8000),   --查询语句,如果查询语句中使用了order by ,请加上top 100 percent
@path nvarchar(1000),   --文件存放目录
@fname nvarchar(250),   --文件名
@sheetname varchar(250)=''  --要创建的工作表名,默认为文件名
as 
declare @err int,@src nvarchar(255),@desc nvarchar(255),@out int
declare @obj int,@constr nvarchar(1000),@sql varchar(8000),@fdlist varchar(8000),@tmpsql varchar(8000)
declare @sheetcount int,@sheetnow int, @recordcount int, @recordnow int
declare @sheetsql varchar(8000)--创建页的sql

declare @pagesize int
set @pagesize = 65000--sheet分页的大小
--set @pagesize = 1000

--参数检测
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)
set @sql=@path+@fname
insert into #tb exec master..xp_fileexist @sql

--数据库创建语句
set @sql=@path+@fname
if exists(select 1 from #tb where a=1)


 set @constr='DRIVER={Microsoft Excel Driver (*.xls)};DSN='''';READONLY=FALSE'
       +';CREATE_DB="'+@sql+'";DBQ='+@sql
else
 set @constr='Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties="Excel 8.0;HDR=YES'
    +';DATABASE='+@sql+'"'

--连接数据库
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

--创建表的SQL
declare @tbname sysname

set @tbname='##tmp_'+convert(varchar(38),newid())

declare @tbtmpid nvarchar(50)
set @tbtmpid ='tmp_'+convert(varchar(38),newid())+''


--有序列ID @tbtmpid的临时表
set @sql='select Identity(int,1,1) as ['+@tbtmpid+'], a.* into ['+@tbname+'] from ( select top 100 percent b.* from ( '+@sqlstr+') b) a'
exec(@sql)

--print(@sql)


--取得记录总数
set @recordcount= @@rowcount
if @recordcount=0 return
--print @recordcount

select @sql='',@fdlist=''
select @fdlist=@fdlist+',['+a.name+']'
 ,@sql=@sql+',['+a.name+'] '
  +case 
   when b.name like '%char' 
   then case when a.length>255 then 'memo'
    else 'text('+cast(a.length as varchar)+')' end
   when b.name like '%int' or b.name='bit' then 'int'
   when b.name like '%datetime' then 'datetime'
   when b.name like '%money' then 'money'
   when b.name like '%text' then 'memo'
   else b.name end
FROM tempdb..syscolumns a left join tempdb..systypes b on a.xtype=b.xusertype
where b.name not in('image','uniqueidentifier','sql_variant','varbinary','binary','timestamp')
 and a.id=(select id from tempdb..sysobjects where name=@tbname)
and a.name <> @tbtmpid

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

--列数为零
if @@rowcount=0 return


set @sheetsql = @sql

--print @sheetsql


--导入数据
--页数
set @sheetcount = CEILING(@recordcount/CAST(@pagesize as float))
--print @sheetcount
--只是一个页而已
IF @sheetcount = 1 BEGIN
    --print '只是一个页而已'

    set @sql='create table ['+@sheetname
     +']('+substring(@sheetsql,2,8000)+')'
     
    
    exec @err=sp_oamethod @obj,'execute',@out out,@sql
    if @err<>0 goto lberr
    



    set @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=YES
       ;DATABASE='+@path+@fname+''',['+@sheetname+'$])'
    
    exec('insert into '+@sql+'('+@fdlist+') select '+@fdlist+' from ['+@tbname+']')
END

--多个页

set @sheetnow = @sheetcount
set @recordnow= 0 
IF @sheetcount > 1 BEGIN


    --print '多个页'
WHILE @sheetnow > 0 BEGIN

    --创建页
    set @sql='create table ['+@sheetname+'_'+ convert(nvarchar(80),@sheetcount - @sheetnow + 1)
    +']('+substring(@sheetsql,2,8000)+')'
     
    
    exec @err=sp_oamethod @obj,'execute',@out out,@sql
    if @err<>0 goto lberr
    
    --print @sql
    --创建页end


    IF @sheetnow = @sheetcount BEGIN
        set @tmpsql ='select top '+str(@pagesize)+' '+@fdlist+' from ['+@tbname+']'
        set @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=YES
    ;DATABASE='+@path+@fname+''',['+@sheetname+'_'+convert(nvarchar(80),@sheetcount - @sheetnow + 1)+'$])'
        
        exec('insert into '+@sql+'('+@fdlist+') '+ @tmpsql)
    END
    IF @sheetnow < @sheetcount BEGIN    
        set @tmpsql='select top '+str(@pagesize)+' '+@fdlist+' from ['+@tbname+'] where ['+@tbtmpid
    +'] not in ( select top '+str(@recordnow-@pagesize)+' ['+@tbtmpid+'] from ['+@tbname+'])'

        set @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=YES
    ;DATABASE='+@path+@fname+''',['+@sheetname+'_'+ convert(nvarchar(80),@sheetcount - @sheetnow + 1)+'$])'
        
        exec('insert into '+@sql+'('+@fdlist+') '+ @tmpsql)
        --print (@tmpsql)    
        --exec(@tmpsql)
    END
    
    --print (@tmpsql)    

    --exec (@tmpsql)    

    set @recordnow = @pagesize*(@sheetcount-@sheetnow+2)
    set @sheetnow = @sheetnow -1
END
END

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


exec @err=sp_oadestroy @obj

--结束返回
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


[其他解释]
我终于回到CSDN了,忘记结贴,现在就结啊!

热点排行