我的存储过程如下现在的问题是执行存储过程是成功的,但导出的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   
    
    

解决方案 »

  1.   

    如果关不掉说明进程中还执行EXCEL的进程。开启'Ole Automation Procedures'的服务sp_configure 'show advanced options', 1;
    GO
    RECONFIGURE;
    GO
    sp_configure 'Ole Automation Procedures', 1;
    GO
    RECONFIGURE;
    GOEXEC sp_configure 'Ole Automation Procedures';
    GO
    exec H_SqlToExcel 'c:\','test2.xls','sheet1','SELECT TOP 10 PersonName FROM PersonalBaseInfo
    红色的你详细看一下我机器 sql2005 office2003 执行没有问题
      

  2.   

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

  3.   

    建议使用clr存储过程http://blog.csdn.net/jinjazz/archive/2009/04/29/4138000.aspx
      

  4.   

    我在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' 试下
      

  5.   


    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)--创建页的sqldeclare @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 lberrexec @err=sp_oamethod @obj,'open',null,@constr
    if @err<>0 goto lberr--创建表的SQL
    declare @tbname sysnameset @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 @recordcountselect @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 <> @tbtmpidset @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
    ENDset @sql='drop table ['+@tbname+']'
    exec(@sql)
    exec @err=sp_oadestroy @obj--结束返回
    returnlberr:
     exec sp_oageterrorinfo 0,@src out,@desc out
    lbexit:
     select cast(@err as varbinary(4)) as 错误号
      ,@src as 错误源,@desc as 错误描述
     select @sql,@constr,@fdlist
      

  6.   

    我终于回到CSDN了,忘记结贴,现在就结啊!