1. set ANSI_NULLS ON
  2. set QUOTED_IDENTIFIER ON
  3. go
  4.  
  5. /*
  6. 将查询结果集直接导出到excel文件中(包含表头,别名不能包含\'(\'),通过SQLServer数据库内置对象提高数据导出速率(事理 2011.5)
  7. exec proc_ExportDataToExcel \'.\SQL2005\',\'OA\',\'asdfef85\',\'\',\'select top 10* from SL_User where UserId<500\',\'D:/1.xls\'
  8. 判断xp_cmdshell存储过程是否存在select count(*) from master.dbo.sysobjects where xtype=\'X\' and name=\'xp_cmdshell\'
  9. 注意:使用此存储过程,数据库登录用户要有sysadmin权限,需要创建表AppLock管理xp_cmdshell的开启与关闭
  10. create table AppLock (Id int not null identity(1,1) primary key,SessionCount int not null,Name varchar(50) not null)
  11. insert into AppLock values(0,\'proc_ExportDataToExcel\')
  12. */
  13. create PROC [dbo].[proc_ExportDataToExcel]
  14. (
  15. @server nvarchar(50),--数据库服务名称
  16. @database nvarchar(50),--数据库名称
  17. @uid nvarchar(50),--数据库登录用户名
  18. @pwd varchar(50),--数据库登录密码
  19. @selectSQL varchar(7000),--查询语句
  20. @fileSavePath nvarchar(500)--excel文件存放目录如,D:/1.xls
  21. )
  22. AS
  23. BEGIN
  24. declare @errorSum int --记录错误标志
  25. declare @sql varchar(8000)
  26. declare @tableName varchar(55)--随机临时表名称
  27. declare @tempTableName varchar(55)
  28. set @errorSum = 1
  29.  
  30. --生成随机名称,防止多个人同时导出数据问题
  31. select @tableName = replace(\'##ExportDataToExcel\'+Convert(varchar(36),newid()),\'-\',\'\')
  32. set @tempTableName=@tableName+\'Temp\'
  33. --拼接复制表结构的sql语句
  34. declare @tempSQL varchar(7000)
  35. --判断第一个select后面是否有top
  36. declare @hasTop varchar(10)
  37. declare @index int
  38. set @index=charindex(\' \',@selectSQL)
  39. set @hasTop=lower(ltrim(substring(@selectSQL,@index+1,10)))
  40. set @hasTop=substring(@hasTop,0,4)
  41. if(@hastop=\'top \')
  42. begin
  43. --将其它top换成top 0
  44. set @tempSQL=substring(@selectSQL,12,len(@selectSQL)-11)--截取"select top "之后字符串
  45. set @index=patindex(\'%[0-9][^0-9]%\', @tempSQL)--查询top后最后一个数字位置
  46. set @tempSQL=\'select top 0 \'+substring(@tempSQL,@index+1,len(@tempSQL)-@index)
  47. end
  48. else
  49. begin
  50. --在第一个select后面加上top 1
  51. set @tempSQL=\'select top 0 \'+substring(@selectSQL,8,len(@selectSQL)-7)
  52. end
  53.  
  54. --通过查询语句创建用于复制表结构的空临时表
  55. begin try
  56. set @sql=\'select * into \'+@tempTableName+\' from (\'+@tempSQL+\') as temp where 1=0\'
  57. exec (@sql)
  58. set @errorSum = @errorSum+1
  59. end try
  60. begin catch
  61. raiserror(\'创建复制表结构的空临时表失败!\',16,1)
  62. return @errorSum
  63. end catch;
  64. --查询表结构
  65. declare @columnName nvarchar(4000)
  66. declare @columnName2 nvarchar(4000)
  67. select @columnName=isnull(@columnName+\',\',\'\')+\'\'\'\'+SC.name+\'\'\'\',@columnName2=
  68. case when ST.name in(\'text\',\'ntext\') then isnull(@columnName2+\',\',\'\')+SC.name
  69. when ST.name in(\'char\',\'varchar\') then isnull(@columnName2+\',\',\'\')+\'cast(\'+SC.name+\' as varchar(\'+cast((case when SC.length<255 then 255 else SC.length end) as varchar)+\')) \'+SC.name
  70. when ST.name in(\'nchar\',\'nvarchar\') then isnull(@columnName2+\',\',\'\')+\'cast(\'+SC.name+\' as nvarchar(\'+cast((case when SC.length<255 then 255 else SC.length end) as varchar)+\')) \'+SC.name
  71. else isnull(@columnName2+\',\',\'\')+\'cast(\'+SC.name+\' as varchar(1000)) \'+SC.name end
  72. from tempdb..sysobjects SO,tempdb..syscolumns SC,tempdb..systypes ST
  73. where SO.id=SC.id and SO.xtype=\'U\' and SO.status>=0 and SC.xtype=ST.xusertype and SO.name=@tempTableName
  74. and ST.name not in(\'image\',\'sql_variant\',\'varbinary\',\'binary\')
  75. order by SC.colorder
  76. declare @dropTableSql varchar(200)
  77. begin try
  78. --创建全字符串类型的空临时表
  79. set @sql=\'select * into \'+@tableName+\' from (select \'+@columnName2+\' from \'+@tempTableName+\' where 1=0) as temp\'
  80. exec (@sql)
  81. --删除临时空临时表
  82. set @dropTableSql=\'if exists(select * from tempdb..sysobjects where name=\'\'\'+@tempTableName+\'\'\') drop table \'+@tempTableName
  83. exec (@dropTableSql)
  84. --插入列名(表头)
  85. set @sql=\'insert into \'+@tableName+\' values(\'+@columnName+\')\'
  86. exec (@sql)
  87. --插入数据到临时表
  88. set @sql=\'insert into \'+@tableName+\' select * from (\'+@selectSQL+\') as temp\'
  89. exec (@sql)
  90. set @errorSum = @errorSum+1
  91. end try
  92. begin catch
  93. raiserror(\'创建数据临时表或往临时表中插入数据失败!\',16,1)
  94. exec (@dropTableSql)
  95. return @errorSum
  96. end catch
  97. --删除数据临时表
  98. set @dropTableSql=\'if exists(select * from tempdb..sysobjects where name=\'\'\'+@tableName+\'\'\') drop table \'+@tableName
  99. --导出数据
  100. begin try
  101. declare @sessionCount int
  102. select @sessionCount=SessionCount from AppLock where [Name]=\'proc_ExportDataToExcel\'
  103. if @sessionCount=0
  104. begin
  105. /*开启xp_cmdshell,数据库登录用户要有sysadmin权限*/
  106. begin try
  107. EXEC sp_configure \'show advanced options\', 1
  108. RECONFIGURE
  109. EXEC sp_configure \'xp_cmdshell\', 1
  110. RECONFIGURE
  111. EXEC sp_configure \'show advanced options\', 0
  112. RECONFIGURE
  113. end try
  114. begin catch
  115. end catch;
  116. end
  117.  
  118. --更新一个表时,默认有排他锁
  119. update AppLock set SessionCount=SessionCount+1 where [Name]=\'proc_ExportDataToExcel\'
  120. set @sql=\'master..xp_cmdshell \'\'bcp "select * from \'+@database+\'.dbo.\'+@tableName+\'" queryout "\'+@fileSavePath+\'" -c -S"\'+@server+\'" -U"\'+@uid+\'" -P"\'+@pwd+\'"\'\'\'
  121. exec (@sql)
  122. update AppLock set SessionCount=SessionCount-1 where [Name]=\'proc_ExportDataToExcel\'
  123. set @errorSum = @errorSum+1
  124.  
  125. declare @sessionCount2 int
  126. select @sessionCount2=SessionCount from AppLock where [Name]=\'proc_ExportDataToExcel\'
  127. if @sessionCount2=0
  128. begin
  129. /*关闭xp_cmdshell,加锁使用才能不造成冲突*/
  130. begin try
  131. EXEC sp_configure \'show advanced options\', 1
  132. RECONFIGURE
  133. EXEC sp_configure \'xp_cmdshell\', 0
  134. RECONFIGURE
  135. EXEC sp_configure \'show advanced options\', 0
  136. RECONFIGURE
  137. end try
  138. begin catch
  139. end catch;
  140. end
  141. end try
  142. begin catch
  143. exec (@dropTableSql)
  144. declare @errorMsg nvarchar(4000)
  145. set @errorMsg=ERROR_MESSAGE()
  146. if(@errorMsg is not null)
  147. raiserror(@errorMsg,16,1)
  148. return @errorSum
  149. end catch;
  150. exec (@dropTableSql) --删除数据临时表
  151. return @errorSum
  152. END

//调用

  1. /// <summary>
  2. /// 导出数据到excel文件中
  3. /// </summary>
  4. /// <param name="selectSQL">select查询sql语句</param>
  5. /// <param name="fileSavePath">文件保存路径</param>
  6. /// <returns>返回消息</returns>
  7. public static void ExportDataToExcel(string selectSQL, string fileSavePath)
  8. {
  9. string connectionString = SQLHelper.ConnectionString;
  10. //获取连接字符串数据库服务器、数据库名称、用户名和密码
  11. Dictionary<string, string> dic = new Dictionary<string, string>();
  12. string[] tempArray = connectionString.Split(new char[] { \';\' }, StringSplitOptions.RemoveEmptyEntries);
  13. foreach (string str in tempArray)
  14. {
  15. string[] temp = str.Split(\'=\');
  16. dic.Add(temp[0].Trim().ToLower(), temp[1].Trim());
  17. }
  18. string server = dic.Keys.Contains("data source") ? dic["data source"] : dic["server"];
  19. string database = dic.Keys.Contains("initial catalog") ? dic["initial catalog"] : dic["database"];
  20. string pwd = string.Empty;
  21. if (dic.Keys.Contains("password"))
  22. pwd = dic["password"];
  23. else if (dic.Keys.Contains("pwd"))
  24. pwd = dic["pwd"];
  25. string userID = string.Empty;
  26. if (dic.Keys.Contains("user id"))
  27. userID = dic["user id"];
  28. SQLHelper helper = new SQLHelper();
  29. helper.InitStoredProcedure("[proc_ExportDataToExcel]");
  30. helper.AddParameter("@server", server);
  31. helper.AddParameter("@database", database);
  32. helper.AddParameter("@uid", userID);
  33. helper.AddParameter("@pwd", pwd);
  34. helper.AddParameter("@selectSQL", selectSQL);
  35. helper.AddParameter("@fileSavePath", fileSavePath);
  36. helper.AddReturnParameter("@errorSum");
  37. try
  38. {
  39. helper.ExecuteNonQuery();
  40. int result = (int)helper.GetValue("@errorSum");
  41. if (result == 1)
  42. throw new Exception("创建复制表结构的空临时表失败!");
  43. else if (result == 2)
  44. throw new Exception("创建临时表或往临时表中插入数据失败!");
  45. else if (result == 3)
  46. throw new Exception("导出数据失败!");
  47. else if (result == 4)////"导出成功!";
  48. {
  49. }
  50. }
  51. catch (Exception ex)
  52. {
  53. throw ex;
  54. }
  55. }

第二种

  1. /*有存在1.xls文件,并且设置好了表头
  2. INSERT INTO OPENDATASOURCE(\'Microsoft.JET.OLEDB.4.0\',
  3. \'Extended Properties=Excel 8.0;Data source=d:\1.xls\')...[sheet1$]
  4. select 销售数量,销售金额,零售金额,专柜代码,供应商品名称,成本,毛利额,毛利率 from (select sum( quantity )as 销售数量 ,sum( salessum ) as 销售金额,sum( salessum +rebatesum ) as 零售金额,d_product_sale_list.shoppeno as 专柜代码 ,\'(\'+isnull(A_TradeMember.memcode,0) + \')\'+isnull(A_TradeMember.memname,0) as 供应商品名称, sum(isnull(cost,0)+isnull(costtax,0)) as 成本,sum(salessum)-sum( isnull(cost,0) +isnull(costtax,0) ) as 毛利额,case when sum(salessum)<>0 then (sum(salessum)-sum( isnull(cost,0) +isnull(costtax,0) ))/sum(salessum)else 0 end as 毛利率 from (SELECT * FROM d_product_sale_list UNION ALL SELECT * FROM d_product_sale_list20114) d_product_sale_list , A_TradeMember,a_protocol where shoppeno is not null and a_protocol.mem_id = A_TradeMember.mem_id and saledate>=\'2011-4-01\' and saledate<=\'2011/4/22 0:00:00\' group by d_product_sale_list.shoppeno, A_TradeMember.memname,A_TradeMember.memcode) a
  5. */

 

版权声明:本文为slyzly原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/slyzly/articles/2657424.html