日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

大数据量导出Excel ---待测试

發布時間:2025/7/14 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大数据量导出Excel ---待测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go


/*--數據導出EXCEL

導出查詢中的數據到Excel,包含字段名,文件為真正的Excel文件
如果文件不存在,將自動創建文件
如果表不存在,將自動創建表
基于通用性考慮,僅支持導出標準數據類型
--Modify
1、修改鄒建的錯誤:關于provider的書寫
在openrowset時為database
在ADODb.connection.open時為data source,一個很不容易找到的錯誤,否則0x80004005 Microsoft JET Database Engine 不能執行選定查詢
2、執行過程過長時,中途無法取消
3、一些限制
--Jet SQL無法修改列名,應使用ADOX.Catagory
--SQLServer2005索引最大為1284 bytes,order by 最大為8060 bytes
--grant exec分配不了權限
4、要對@varQuerySQL中結果集排序,請在@varOrderBy指定結果集中的列,存儲過程會按此排序,不要再在@varQuerySQL中再排序

--鄒建 2003.10(引用請保留此信息)--*/


/*--調用示例--

--表的聯合
p_QueryToExcel @varQuerySQL= 'select top 65000 A.* from a inner join B on A.a1=B.a1'
,@varExcelFullPath= 'E:\aa21.xls',@varSheetName= 'sheet'

select * from liupeng --256003
--102400條記錄
--時間:
--@varQuerySQL沒有order by TopName,Identitier
1:50,1:21, 1:55, 1:27(加索引), 1:34(加索引)
--@varQuerySQL有order by
大于9:00
--Select語句列必須帶函數的列必須有別名
p_QueryToExcel @varQuerySQL= 'select MetaID as 標識,Title as 書名,Creator as 作者,Publisher as 出版者,Price as 單價,CopyNum as 復本數,Identitier as 分類號,TopName as 類目,issuedate as 出版時間,ISBN,publishdate as 公布時間,(case
when IsRef= 0 then ''否''
when IsRef = 1 then ''是''
else '''' end ) as 是否教參
from [liupeng]
where CategoryTypeID=1 ',@varExcelFullPath= 'E:\aa3.xls',@varSheetName= 'sheet'

select count(*) from ast_document --334138
--102400條記錄
--時間:
--@varQuerySQL沒有order by TopName,Identitier
2:00, 1:10, 1:27, 1:21, 1:20

p_QueryToExcel @varQuerySQL=' select top 2000 MetaID as 標識,TopIdentitier,DocID,Title,Creator,Publisher,Price,CopyNum,Identitier,TopName,substring(convert(varchar, issuedate, 20), 1, 7) as 出版日期,ISBN,substring(convert(varchar,publishdate, 20), 1, 10) as 發布日期,(case
when IsRef= 0 then''否''
when IsRef = 1 then ''是''
else ''''end ) as IsRef
,Abstract
from [liupeng]'
,@varExcelFullPath= 'E:\aa004.xls',@varSheetName= 'sheet',@varOrderBy='TopIdentitier,DocID'

p_QueryToExcel @varQuerySQL= 'select top 102400
DocID,
MetaTypeID,
MetaID,
Title,
Creator,
[Year],
Publisher,
PublishDate,
Price,
ISBN,
IssueDate,
IsScan,
Status,
InsertedTime,substring(Abstract,1,255) as 摘要 from ast_document'
,@varExcelFullPath= 'E:\aa2.xls',@varSheetName= 'sheet',@varOrderBy='MetaID,Title'

--Excel 12:[Sheet1$]則,會報錯“書簽無效”,應使用'select * from [Sheet1$]'
insert into OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0;Database=D:\test.xlsx;',
'select * from [Sheet1$]') select top 10 DocID from Test.dbo.ast_document

--在Excel 12中一個sheet中加入10萬條記錄比在多個Sheet中加入10萬條記錄要滿很多
--因此不用Excel 12存
SELECT *
FROM OPENDATASOURCE( 'Microsoft.Jet.OLEDB.4.0',
'Data Source=F:\aa.xls; Extended properties="Excel 8.0;HDR=YES"')...sheet$

*/

ALTER proc [dbo].[p_QueryToExcel]
@varQuerySQL varchar(8000), --@varQuerySQL:查詢語句,各列必須有名稱,沒有的需要別名,由于
--如果查詢語句中使用了order by,請加上top 100 percent
--對是否包含where分類限制不做要求
@varExcelFullPath nvarchar(4000), --@varExcelFullPath:生成Excel的完整路徑
@varSheetName varchar(512) = 'sheet',
@varOrderBy varchar(512) = '類目', --必須是@varQuerySQl中的列名
@varArrayHiddenCols varchar(1024) = 'TopIdentitier,DocID'
as
begin
--聲明和初始化變量

declare @varSheetName_pre varchar(1024)
declare @intOneSheetMaxNumber int
declare @intRecCount int
declare @sinSheetNumber smallint
declare @sinCircle int
declare @varTempSQL varchar(8000)

set @intOneSheetMaxNumber = 50000
set @sinSheetNumber = 1
set @varExcelFullPath = convert(varchar(8000),ltrim(rtrim(@varExcelFullPath)))
set @varQuerySQL = lower(ltrim(rtrim(@varQuerySQL)))
set @sinCircle = 0
set @varSheetName_pre = @varSheetName
set @varOrderBy = ltrim(rtrim(@varOrderBy))
set @varArrayHiddenCols = lower(ltrim(rtrim(@varArrayHiddenCols)))
--select top 1 1 from ast_document where metaid not in ('CategoryTypeID','DocID')
set @varArrayHiddenCols = replace(@varArrayHiddenCols,',',',') --CategoryTypeID,DocID
print @varArrayHiddenCols
-- set @varOrderByWithNoAliasTable = ltrim(rtrim(@varOrderByWithNoAliasTable))
-- --@varQuerySQL的別名這里取AAA
-- if @varOrderByWithNoAliasTable is null or @varOrderByWithNoAliasTable = ''
-- set @varOrderBy = 'Order by AAA.CategoryTypeid, AAA.HiberarchyCode'
-- else
-- set @varOrderBy = 'AAA.' + replace(@varOrderByWithNoAliasTable,',' ,',AAA.' )

/*=================================檢測參數有效性====================*/
----判斷@varExcelFullPath
if (@varExcelFullPath is null) or (@varExcelFullPath='')
begin
RAISERROR ('Excel文件路徑不能為空。',1,1)
return 50001
end

----判斷@varQuerySQL
if (@varQuerySQL is null) or (@varQuerySQL = '')
begin
RAISERROR ('查詢語句不能為空。',1,2)
return 50001
end

----判斷@varQuerySQL 'SQL語句'
----假設用戶沒有惡意調用
set @varTempSQL = @varQuerySQL
if left(@varTempSQL,1) = '('
begin
RAISERROR ('不能將整個SQL語句用括號包起來。',2,16)
return 50002
end

if charindex('select ',@varTempSQL,1) = 0
begin
RAISERROR ('Error 缺少select語句。',2,16)
return 50002
end

if charindex(' aaa',@varTempSQL,1) > 0 or charindex(' bbb',@varTempSQL,1) > 0 or charindex(' myrownumber',@varTempSQL,1) > 0
begin
RAISERROR ('請使用AAA、BBB、MyRowNumber以外的別名。',2,16)
return 50002
end

if left(@varTempSQL,1) = '('
begin
RAISERROR ('不能將整個SQL語句用括號包起來。',2,16)
return 50002
end
--針對'
--set @varQuerySQL = replace(@varQuerySQL,char(39),char(39)+char(39))
/*
if charindex(char(39),@varTempSQL,1) > 0
begin
--RAISERROR ('Error 傳輸的SQL語句不能包含英文撇,請使用''代替。',3,17)
--return 50002
end
*/

if @varOrderBy is null or @varOrderBy =''
begin
RAISERROR ('排序不能為空。',1,5)
return 50001
end
else
begin
set @varOrderBy = 'BBB.' + replace(@varOrderBy,',',',BBB.')
end
print @varOrderBy

--exec ('select 1 from (select * from ast_document where docid < 0) as A')
--select 1以便得到count記錄數,保證@varQuerySQL不包含AAA別名
set @varTempSQL = 'select 1 from (' + @varQuerySQL + ') as AAA'
exec (@varTempSQL)

--@@rowcount在下一個begin...end之后就成為0
set @intRecCount = @@rowcount
if @intRecCount = 0
begin
RAISERROR ('查詢記錄集為空。',1,5)
return 50001
end
print @intRecCount


declare @varTopCategoryCode varchar(256)
declare @varTopCategoryName varchar(512)
declare @err int, @src varchar(255), @desc varchar(255), @out int --Error跟蹤
declare @obj int, @constr varchar(1000), @fdlist varchar(8000), @fdlist_AAA varchar(8000)
declare @tbname sysname

--檢查Excel文件是否已經存在
create table #tb(a bit,b bit,c bit)
set @varExcelFullPath = ltrim(rtrim(@varExcelFullPath))

insert into #tb
exec master..xp_fileexist @varExcelFullPath
print 'xp_fileexist'+@varExcelFullPath
--select * from #tb
/*
xp_fileexist 返回的三個列, 分別代表

文件已存在 文件是目錄 父目錄已存在
----- ----- ------
0 0 1
*/

/*
declare @saveas varchar(2048),@sheet int

set @saveas = 'ActiveWorkbook.SaveAs("'+@varExcelFullPath+'")'

exec @err = sp_oacreate 'excel.application' ,@obj output
if @err <> 0 goto lberr

exec @err = sp_oamethod @obj ,'workbooks.add' ,@sheet output
if @err <> 0 goto lberr

exec @err = sp_oamethod @obj ,@saveas
if @err <> 0 goto lberr

--exec @err = sp_oamethod @obj ,'ActiveWorkbook.Save'
if @err <> 0 goto lberr

exec @err = sp_oamethod @obj ,'Workbooks.Close'
if @err <> 0 goto lberr

exec @err = sp_oamethod @obj ,'quit'
exec @err = sp_oadestroy @obj

return
*/

--數據庫創建語句
set @varTempSQL = @varExcelFullPath
if exists(select 1 from #tb where a=1)
begin
--set @constr= 'DRIVER={Microsoft Excel Driver (*.xls)};DSN= '''';READONLY=FALSE '
-- + ';CREATE_DB= "'+@sql+ '";DBQ='+@sql
RAISERROR ('暫不支持對已經存在的Excel,做導出操作。',1,5)
return 50001
end
else
set @constr= 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+@varExcelFullPath+ ';Extended Properties="Excel 8.0;HDR=YES"'
--set @constr= 'Provider=Microsoft.ACE.OLEDB.12.0;Data Source='+@varExcelFullPath+ ';Extended Properties="Excel 12.0;HDR=YES"'


--連接數據庫
EXEC @err=sp_OACreate 'ADODB.Connection', @obj OUT
print '連接數據庫1'+convert(varchar(50),@obj)
if @err <> 0 goto lberr

EXEC @err=sp_OASetProperty @obj,'ConnectionString', @constr
if @err <> 0 goto lberr

exec @err=sp_oamethod @obj, 'Open'
print '連接數據庫2'+@constr
if @err <> 0 goto lberr

print '創建臨時表1'

--創建相同表結構的臨時表
set @tbname= '##tmp_'+convert(varchar(38),newid())
set @varTempSQL= 'select top 1 AAA.* into ['+@tbname+ '] from ('+@varQuerySQL+ ') AAA'
print '創建臨時表2'+@varTempSQL
exec(@varTempSQL)

set @varTempSQL = ''
set @fdlist = ''
set @fdlist_AAA = ''
select @fdlist=@fdlist+ ',['+a.name+']'
,@varTempSQL=@varTempSQL+',['+a.name+'] '
+case
when b.name like '%char'
then case when a.length> 255 then 'text(255)'
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 charindex(a.name, @varArrayHiddenCols)=0

select @fdlist_AAA=@fdlist_AAA+ ',AAA.['+a.name+']'
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 charindex(a.name, @varArrayHiddenCols)=0

print @fdlist + ' ' +@fdlist_AAA
print'轉換數據類型'

/*=====================分頁插入Excel的Sheet=======================*/
--如果不按分類存放

--獲得記錄總數@intRecCount,上面判斷時已經獲得
----設置Sheet名稱
----判斷@intRecCount與@intOneSheetMaxNumber大小,定義Sheet名稱后
----分頁插入各個Sheet

--如果<=@intOneSheetMaxNumber
if @intRecCount <= @intOneSheetMaxNumber
begin
set @varSheetName = @varSheetName_pre + '1'
--直接創建Excel和導入數據
set @varTempSQL= 'create table ['+@varSheetName + '] ('
+ substring(@varTempSQL,2,8000)+ ')'
set @fdlist=substring(@fdlist,2,8000)
set @fdlist_AAA=substring(@fdlist_AAA,2,8000)

print '準備創建Table '+@varTempSQL
exec @err=sp_oamethod @obj, 'Execute',@out out,@varTempSQL
if @err <> 0 goto lberr

--為導入數據
set @varTempSQL= 'openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=Yes;database='+@varExcelFullPath+ ''',['+@varSheetName+ '$])'
--set @varTempSQL= 'openrowset(''Microsoft.ACE.OLEDB.12.0'',''Excel 12.0;HDR=Yes;database='+@path+@fname+ ''',''select * from ['+@varSheetName+ '$]'')'
print '導入數據:'+'insert into '+@varTempSQL+ '('+@fdlist+ ') select '+@fdlist_AAA+ ' from ('+@varQuerySQL+ ') as AAA'
exec('insert into '+@varTempSQL+ '('+@fdlist+ ') select '+@fdlist_AAA+ ' from ('+@varQuerySQL+ ') as AAA')
end
--如果>@intOneSheetMaxNumber
else
begin
set @sinSheetNumber = @intRecCount / @intOneSheetMaxNumber
+ (case (@intRecCount % @intOneSheetMaxNumber) when 0 then 0 else 1 end)

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

while ( @sinCircle < @sinSheetNumber )
begin
set @varSheetName = @varSheetName_pre + convert(varchar(50),@sinCircle+1)
print '第 ' + convert(varchar(50),@sinCircle+1) + ' 個Sheet / 總共 ' + convert(varchar(50),@sinSheetNumber) + ' 個Sheet'
--直接創建Excel和導入數據
declare @varTempSQL2 varchar(8000)
set @varTempSQL2 = ''
select @varTempSQL2= 'create table ['+@varSheetName
+ '] ('+substring(@varTempSQL,2,8000)+ ')'


print '準備創建Table ' + @varTempSQL2
exec @err=sp_oamethod @obj, 'Execute',@out out,@varTempSQL2
print 'create table :'+@varTempSQL
if @err <> 0 goto lberr

--為導入數據
/*
WITH OrderedTable AS
(
SELECT BBB.*,ROW_NUMBER() OVER (ORDER BY Docid) AS 'MyRowNumber'
FROM (@varQuerySQL) as BBB
)
insert into openrowset() (@fdlist)
SELECT @fdlist
FROM OrderedTable
WHERE MyRowNumber BETWEEN (@intOneSheetMaxNumber * @sinCircle) AND (@intOneSheetMaxNumber * (@sinCircle+1))
*/
--set @varTempSQL= 'openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=Yes;database='+@varExcelFullPath+ ''',['+@varSheetName+ '$])'
--set @varTempSQL= 'openrowset(''Microsoft.ACE.OLEDB.12.0'',''Excel 12.0;HDR=Yes;database='+@path+@fname+ ''',''select * from ['+@varSheetName+ '$]'')'

set @varTempSQL2 = 'WITH OrderedTable AS
(
SELECT BBB.*,ROW_NUMBER() OVER (ORDER BY '+@varOrderBy +') AS ''MyRowNumber''
FROM (' + @varQuerySQL + ') as BBB
)
insert into openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 8.0;HDR=Yes;database='+@varExcelFullPath+ ''',['+@varSheetName+ '$])'
+ ' select ' + @fdlist + ' FROM OrderedTable WHERE MyRowNumber BETWEEN ' + convert(varchar(50),@intOneSheetMaxNumber * @sinCircle+1) + ' AND ' + convert(varchar(50),@intOneSheetMaxNumber * (@sinCircle+1))

print '導入數據:'+@varTempSQL2
exec(@varTempSQL2)

set @sinCircle = @sinCircle + 1
end
end


--關閉和釋放OA對象
EXEC @err=sp_OAMethod @obj, 'Close'
EXEC @err=sp_OAMethod @obj, 'Dispose'
print 'sp_oadestroy'+convert(varchar(50),@obj)
EXEC @err=sp_OADestroy @obj

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

return
lberr:
exec sp_oageterrorinfo 0,@src out,@desc out
lbexit:
select cast(@err as varbinary(4)) as 錯誤號
,@src as 錯誤源,@desc as 錯誤描述
select @varTempSQL,@constr,@fdlist

end

轉載于:https://www.cnblogs.com/y0umer/archive/2011/09/29/3839295.html

總結

以上是生活随笔為你收集整理的大数据量导出Excel ---待测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。