知识大全 SQL2005CLR函数扩展-数据导出的实现详解
Posted 文件
篇首语:与其积攒满箱子的金银,不如积攒满肚子的学问。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 SQL2005CLR函数扩展-数据导出的实现详解相关的知识,希望对你有一定的参考价值。
SQL2005CLR函数扩展-数据导出的实现详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQLServer数据导出到excel有很多种方法 比如dts ssis 还可以用sql语句调用openrowset 我们这里开拓思路 用CLR来生成Excel文件 并且会考虑一些方便操作的细节 下面我先演示一下我实现的效果 先看测试语句 exec BulkCopyToXls select * from testTable d:/test testTable /* 开始导出数据 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 文件 d:/test/testTable xls 共 条 大小 字节 导出数据完成 共 条数据 耗时 ms */ 上面的BulkCopyToXls存储过程是自定的CLR存储过程 他有四个参数 第一个是sql语句用来获取数据集 第二个是文件保存的路径 第三个是结果集的名字 我们用它来给文件命名 第四个是限制单个文件可以保存多少条记录 小于等于 表示最多 条 前 三个参数没有什么特别 最后一个参数的设置可以让一个数据集分多个excel文件保存 比如传统excel的最大容量是 条数据 我们这里参数设 置为 就表示导出达到这个数字之后自动写下一个文件 如果你设置了比如 那么每导出 条就会自动写下一个文件 另外每个文件都可以输出字段名作为表头 所以单个文件最多容纳 条数据 用微软公开的biff 格式通过二进制流生成excel 服务器无需安装excel组件 而且性能上不会比sql自带的功能差 万多条数据 M 用了 秒完成 下面我们来看下CLR代码 通过sql语句获取DataReader 然后分批用biff格式来写xls文件
复制代码 代码如下: using System; using System Data; using System Data SqlClient; using System Data SqlTypes; using Microsoft SqlServer Server; public partial class StoredProcedures /// <summary> /// 导出数据 /// </summary> /// <param name=sql></param> /// <param name=savePath></param> /// <param name=tableName></param> /// <param name=maxRecordCount></param> [Microsoft SqlServer Server SqlProcedure ] public static void BulkCopyToXls(SqlString sql SqlString savePath SqlString tableName SqlInt maxRecordCount) if (sql IsNull || savePath IsNull || tableName IsNull) SqlContext Pipe Send(" 输入信息不完整!" ); ushort _maxRecordCount = ushort MaxValue ; if (maxRecordCount IsNull == false && maxRecordCount Value < ushort MaxValue&&maxRecordCount Value> ) _maxRecordCount = (ushort )maxRecordCount Value; ExportXls(sql Value savePath Value tableName Value _maxRecordCount); /// <summary> /// 查询数据 生成文件 /// </summary> /// <param name=sql></param> /// <param name=savePath></param> /// <param name=tableName></param> /// <param name=maxRecordCount></param> private static void ExportXls(string sql string savePath string tableName System UInt maxRecordCount) if (System IO Directory Exists(savePath) == false ) System IO Directory CreateDirectory(savePath); using (SqlConnection conn = new SqlConnection ("context connection=true" )) conn Open(); using (SqlCommand mand = conn CreateCommand()) mand CommandText = sql; using (SqlDataReader reader = mand ExecuteReader()) int i = ; int totalCount = ; int tick = System Environment TickCount; SqlContext Pipe Send(" 开始导出数据" ); while (true ) string fileName = string Format(@" / xls" savePath tableName i++); int iExp = Write(reader maxRecordCount fileName); long size = new System IO FileInfo (fileName) Length; totalCount += iExp; SqlContext Pipe Send(string Format(" 文件 共 条 大小 字节" fileName iExp size ToString("### ###" ))); if (iExp < maxRecordCount) break ; tick = System Environment TickCount tick; SqlContext Pipe Send(" 导出数据完成" ); SqlContext Pipe Send(" " ); SqlContext Pipe Send(string Format(" 共 条数据 耗时 ms" totalCount tick)); /// <summary> /// 写单元格 /// </summary> /// <param name=writer></param> /// <param name=obj></param> /// <param name=x></param> /// <param name=y></param> private static void WriteObject(ExcelWriter writer object obj System UInt x System UInt y) string type = obj GetType() Name ToString(); switch (type) case "SqlBoolean" : case "SqlByte" : case "SqlDecimal" : case "SqlDouble" : case "SqlInt " : case "SqlInt " : case "SqlInt " : case "SqlMoney" : case "SqlSingle" : if (obj ToString() ToLower() == "null" ) writer WriteString(x y obj ToString()); else writer WriteNumber(x y Convert ToDouble(obj ToString())); break ; default : writer WriteString(x y obj ToString()); break ; /// <summary> /// 写一批数据到一个excel 文件 /// </summary> /// <param name=reader></param> /// <param name=count></param> /// <param name=fileName></param> /// <returns></returns> private static int Write(SqlDataReader reader System UInt count string fileName) int iExp = count; ExcelWriter writer = new ExcelWriter (fileName); writer BeginWrite(); for (System UInt j = ; j < reader FieldCount; j++) writer WriteString( j reader GetName(j)); for (System UInt i = ; i <= count; i++) if (reader Read() == false ) iExp = i ; break ; for (System UInt j = ; j < reader FieldCount; j++) WriteObject(writer reader GetSqlValue(j) i j); writer EndWrite(); return iExp; /// <summary> /// 写excel 的对象 /// </summary> public class ExcelWriter System IO FileStream _wirter; public ExcelWriter(string strPath) _wirter = new System IO FileStream (strPath System IO FileMode OpenOrCreate); /// <summary> /// 写入short 数组 /// </summary> /// <param name=values></param> private void _writeFile(System UInt [] values) foreach (System UInt v in values) byte [] b = System BitConverter GetBytes(v); _wirter Write(b b Length); /// <summary> /// 写文件头 /// </summary> public void BeginWrite() _writeFile(new System UInt [] x x ); /// <summary> /// 写文件尾 /// </summary> public void EndWrite() _writeFile(new System UInt [] xa ); _wirter Close(); /// <summary> /// 写一个数字到单元格x y /// </summary> /// <param name=x></param> /// <param name=y></param> /// <param name=value></param> public void WriteNumber(System UInt x System UInt y double value) _writeFile(new System UInt [] x x y ); byte [] b = System BitConverter GetBytes(value); _wirter Write(b b Length); /// <summary> /// 写一个字符到单元格x y /// </summary> /// <param name=x></param> /// <param name=y></param> /// <param name=value></param> public void WriteString(System UInt x System UInt y string value) byte [] b = System Text Encoding Default GetBytes(value); _writeFile(new System UInt [] x (System UInt )(b Length + ) x y (System UInt )b Length ); _wirter Write(b b Length); ;把上面代码编译为TestExcel dll copy到服务器目录 然后通过如下SQL语句部署存储过程
复制代码 代码如下: CREATE ASSEMBLY TestExcelForSQLCLR FROM d:/sqlclr/TestExcel dll WITH PERMISSION_SET = UnSAFE; go CREATE proc dbo BulkCopyToXls ( @sql nvarchar ( max ) @savePath nvarchar ( ) @tableName nvarchar ( ) @bathCount int ) AS EXTERNAL NAME TestExcelForSQLCLR StoredProcedures BulkCopyToXls go cha138/Article/program/MySQL/201311/29574相关参考
SQL2005CLR函数扩展-关于山寨索引 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!本文只是一
SQL2005CLR函数扩展-繁简转换的实现代码 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQL2005CLR函数扩展-解析天气服务的实现 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
解析SQL2005中如何使用CLR函数获取行号 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! S
知识大全 使用 SQL Server 2005中的 CLR 集成(2)
使用SQLServer2005中的CLR集成(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 使用 SQL Server 2005中的 CLR 集成(3)
使用SQLServer2005中的CLR集成(3) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 使用 SQL Server 2005中的 CLR 集成(1)
使用SQLServer2005中的CLR集成(1) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQLServer时间函数用法详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! SQL中的时间
SQLServer导出导入数据方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一导出导入SQ
知识大全 Sql Server 2005自定义Split函数
SqlServer2005自定义Split函数 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 要