使用OpenRowSet操作Excel Excel导入数据库
使用 OpenRowSet 和 OpenDataSource 访问 Excel 97-2007
测试文件:D:\97-2003.xls和D:\2007.xlsx,两个文件的内容是一模一样的。
测试环境:SQL Server 2000 / 2005。
--------------------------------------------------------------------------------
接口类型
语法一览
注册表设置
单一数据类型列的类型解析
混合数据类型列的自然解析
混合数据类型列的强制解析——IMEX=1
如何解决 NULL 值问题
SQL Server 2000 中的列顺序问题
如何访问隐藏的 Sheet
如何访问非常规命名的 Sheet
--------------------------------------------------------------------------------
接口类型
有两种接口可供选择:Microsoft.Jet.OLEDB.4.0(以下简称 Jet 引擎)和Microsoft.ACE.OLEDB.12.0(以下简称 ACE 引擎)。
Jet 引擎大家都很熟悉,可以访问 Office 97-2003,但不能访问 Office 2007。
ACE 引擎是随 Office 2007 一起发布的数据库连接组件,既可以访问 Office 2007,也可以访问 Office 97-2003。
另外:Microsoft.ACE.OLEDB.12.0 可以访问正在打开的 Excel 文件,而 Microsoft.Jet.OLEDB.4.0 是不可以的。
Microsoft.ACE.OLEDB.12.0 安装文件:
--------------------------------------------------------------------------------
语法一览
使用 Jet 引擎或 ACE 引擎访问,在语法上没有什么的区别。
view plaincopy to clipboardprint?
--> Jet 引擎访问Excel 97-2003
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;IMEX=1;Database=D:\97-2003.xls', 'select * from [Sheet1$]')
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;IMEX=1;Database=D:\97-2003.xls', [Sheet1$])
select * from OpenDataSource('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;IMEX=1;Database=D:\97-2003.xls')...[Sheet1$]
select * from OpenDataSource('Microsoft.Jet.OLEDB.4.0', 'Data Source=D:\97-2003.xls;Extended Properties="Excel 8.0;HDR=Yes;IMEX=1"')...[Sheet1$]
--> ACE 引擎访问Excel 97-2003
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\97-2003.xls', 'select * from [Sheet1$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\97-2003.xls', [Sheet1$])
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\97-2003.xls')...[Sheet1$]
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Data Source=D:\97-2003.xls;Extended Properties="Excel 12.0;HDR=Yes;IMEX=1"')...[Sheet1$]
--> ACE 引擎访问Excel 2007
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\2007.xlsx', 'select * from [Sheet1$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\2007.xlsx', [Sheet1$])
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\2007.xlsx')...[Sheet1$]
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Data Source=D:\2007.xlsx;Extended Properties="Excel 12.0;HDR=Yes;IMEX=1"')...[Sheet1$]
Excel 2007 工作簿文件的扩展名是:xlsx
HDR=Yes/No
可选参数,指定 Excel 表的第一行是否列名,缺省为 Yes,可以在注册表中修改缺省的行为。
IMEX=1
可选参数,将 Excel 表中混合 Intermixed 数据类型的列强制解析为文本。
--------------------------------------------------------------------------------
注册表设置
Microsoft.Jet.OLEDB.4.0
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel
Microsoft.ACE.OLEDB.12.0
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel
FirstRowHasNames
设置 HDR 参数的缺省行为,默认为 Yes。
ImportMixedTypes
设置混合列的强制解析类型,默认为文本 Text。
TypeGuessRows
设置用于解析数据类型的取样行数,默认取样前 8 行。如果设置为 0,将分析所有数据行,但不建议这样做,会影响引擎的性能。
注意:Excel 表数据列是单一列数据类型还是混合列数据类型列,是由取样行决定,而不是整列数据决定。
--------------------------------------------------------------------------------
单一数据类型列的类型解析
Sheet1 的内容如下图所示,涵盖了大部分 Excel 的数据类型,其中 longtext 分别有 256 个 A 和 B。
对于单一数据类型列的类型解析,ACE 引擎和 Jet 引擎是一样的,下面测试 Jet 引擎的数据解析:
view plaincopy to clipboardprint?
use tempdb
go
select * into #type from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=D:\97-2003.xls', 'select * from [Sheet1$]')
select
a.name,
date_type = b.name + case a.xusertype when 231 then '('+ltrim(a.length/2)+')' else '' end
from
syscolumns a inner join systypes b on a.xusertype = b.xusertype
where
a.id = object_id('#type')
drop table #type
use tempdb
go
select * into #type from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=D:\97-2003.xls', 'select * from [Sheet1$]')
select
a.name,
date_type = b.name + case a.xusertype when 231 then '('+ltrim(a.length/2)+')' else '' end
from
syscolumns a inner join systypes b on a.xusertype = b.xusertype
where
a.id = object_id('#type')
drop table #type数据类型解析总结
文本:长度 <= 255,解析为 nvarchar(255),长度 > 255,解析为 ntext。
数值:货币解析为 money,其它均解析为 float。
时间:datetime。
--------------------------------------------------------------------------------
混合数据类型列的自然解析
相对于使用 IMEX=1 的强制解析,不使用 IMEX=1,称为自然解析。下图是 Sheet2 的内容:
对于混合数据类型列的自然解析,ACE 引擎和 Jet 有细节上的区别,先看测试:
view plaincopy to clipboardprint?
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;Database=D:\2007.xlsx', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;Database=D:\2007.xlsx', 'select * from [Sheet2$]')
相同地方
取样行里数值型多于文本型,解析为 float 数值。
取样行里数值型少于文本型,解析为 nvarchar/ntext 文本。
当解析为 float 数值时,文本类型显示为 NULL,这点毫无疑问。
相异地方
取样行里数值型等于文本型,Jet 引擎解析为 float 数值,数值优先,ACE 引擎解析为 nvarchar/ntext 文本,文本优先。
当解析为 nvarchar/ntext 文本时,Jet 引擎将非文本数据显示为 NULL,ACE 引擎正确显示。
--------------------------------------------------------------------------------
混合数据类型列的强制解析——IMEX=1
使用 IMEX=1 选参之后,只要取样数据里是混合数据类型的列,一律强制解析为 nvarchar/ntext 文本。当然,IMEX=1 对单一数据类型列的解析是不影响的。
view plaincopy to clipboardprint?
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;IMEX=1;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;IMEX=1;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;IMEX=1;Database=D:\2007.xlsx', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;IMEX=1;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;IMEX=1;Database=D:\97-2003.xls', 'select * from [Sheet2$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;IMEX=1;Database=D:\2007.xlsx', 'select * from [Sheet2$]')
最后一列(num<str),Jet 引擎的自然解析和强制解析都解析为 nvarchar(255),但是自然解析将数值显示为 NULL,强制解析却能正确显示,这是不一致的地方。
在数据解析的细节方面,ACE 引擎的表现优于 Jet 引擎。在前面提到的文本优先问题、非文本数据的 NULL 值问题,ACE 引擎的解析更合理。
--------------------------------------------------------------------------------
如何解决 NULL 值问题
前 8 行(取样行)是混合数据类型的列,使用 IMEX=1 选参解决。
前 8 行是文本,行之外有非文本的数据,使用 ACE 引擎解决。
前 8 行是数值,行之外又非数值的数据:
将前 8 行其中一行的单元格式数字设置为文本(如果还不行,可能要手工重写该单元格,以应用文本格式,不记得是 Office 97 还是 2000 存在这个问题了);
修改注册表中的 TypeGuessRows(注册表设置),增加取样行数,或设置为 0 全部解析。
目的只有一个,让取样行变成混合数据类型的列,然后使用 IMEX=1 选参解决。
--------------------------------------------------------------------------------
SQL Server 2000 中的列顺序问题
这是 SQL Server 2000 行集函数 OpenRowSet 和 OpenDataSource 本身的问题,与访问接口引擎无关,也与 Excel 版本无关。SQL Server 2005 的 OpenRowSet 和 OpenDataSource 不存在这个问题。
上图是 Sheet3 的内容,连接到 SQL Server 2000 测试看看是什么问题:
view plaincopy to clipboardprint?
--> HDR=Yes
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;Database=D:\97-2003.xls', [Sheet3$])
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;Database=D:\97-2003.xls')...[Sheet3$]
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Data Source=D:\2007.xlsx;Extended Properties="Excel 12.0;HDR=Yes"')...[Sheet3$]
--> HDR=No
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=No;Database=D:\97-2003.xls', [Sheet3$])
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=No;Database=D:\97-2003.xls')...[Sheet3$]
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Data Source=D:\2007.xlsx;Extended Properties="Excel 12.0;HDR=No"')...[Sheet3$]
--> HDR=Yes
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;Database=D:\97-2003.xls', [Sheet3$])
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;Database=D:\97-2003.xls')...[Sheet3$]
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Data Source=D:\2007.xlsx;Extended Properties="Excel 12.0;HDR=Yes"')...[Sheet3$]
--> HDR=No
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=No;Database=D:\97-2003.xls', [Sheet3$])
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=No;Database=D:\97-2003.xls')...[Sheet3$]
select * from OpenDataSource('Microsoft.ACE.OLEDB.12.0', 'Data Source=D:\2007.xlsx;Extended Properties="Excel 12.0;HDR=No"')...[Sheet3$]
返回结果集的列顺序,是按照列名排序,并不是 Excel 表的列顺序。HDR=No 貌似正确,但仔细一看,仍然是按列名排序的。
OpenRowSet(query)
OpenRowSet(query) 可以解决这个列顺序的问题,包括后面的访问隐藏的 Sheet 或非常规命名的 Sheet,都可以用 OpenRowSet(query) 解决。
view plaincopy to clipboardprint?
--> HDR=Yes
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;Database=D:\2007.xlsx', 'select * from [Sheet3$]')
--> HDR=No
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=No;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=No;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=No;Database=D:\2007.xlsx', 'select * from [Sheet3$]')
--> HDR=Yes
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=Yes;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=Yes;Database=D:\2007.xlsx', 'select * from [Sheet3$]')
--> HDR=No
select * from OpenRowSet('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;HDR=No;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=No;Database=D:\97-2003.xls', 'select * from [Sheet3$]')
select * from OpenRowSet('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;HDR=No;Database=D:\2007.xlsx', 'select * from [Sheet3$]')
--------------------------------------------------------------------------------
如何访问隐藏的 Sheet
隐藏 Sheet 的访问情况比较复杂,就不写测试过程了,归纳一下:
使用 OpenRowSet(query) 肯定可以访问。
Excel 2007 任何写法都可以访问(Jet 引擎不能访问 Excel 2007)。
打开的 Excel 文件任何写法都可以访问(Jet 引擎不能访问打开的 Excel 文件)。
--------------------------------------------------------------------------------
如何访问非常规命名的 Sheet
新建一个空白的 Sheet,重命名为 4 保存关闭:
使用 OpenRowSet(query) 可以正常访问。
其它写法,用单引号限定名称 ['4$'] 可以访问。
OpenRowSet(query) 也可以使用单引号限定访问:'select * from [''4$'']'
引出最后一个问题,访问 Excel 97-2003 空白的 Sheet,会返回一行 NULL 值,访问 Excel 2007 空白的 Sheet,返回空结果集,数据类型均解析为 nvarchar(255)。
会出现的问题:
SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。有关启用 'Ad Hoc Distributed Queries' 的详细信息
SQL Server 阻止了对组件 \'Ad Hoc Distributed Queries\' 的访问
在Sql Server中查询一下Excel文件的时候出现问题:
SELECT * FROM OPENROWSET( 'MICROSOFT.JET.OLEDB.4.0','Excel 8.0;IMEX=1;HDR=YES;DATABASE=D:\a.xls',[sheet1$])
结果提示:
SQL Server 阻止了对组件 'Ad Hoc Distributed Queries' 的 STATEMENT'OpenRowset/OpenDatasource' 的访问,因为此组件已作为此服务器安全配置的一部分而被关闭。系统管理员可以通过使用 sp_configure 启用 'Ad Hoc Distributed Queries'。有关启用 'Ad Hoc Distributed Queries' 的详细信息,请参阅 SQL Server 联机丛书中的 "外围应用配置器"。
查询相关资料,找到解决方法:
启用Ad Hoc Distributed Queries:新建查询,输入
exec sp_configure 'show advanced options',1
reconfigure
exec sp_configure 'Ad Hoc Distributed Queries',1
reconfigure
执行
使用完成后,关闭Ad Hoc Distributed Queries:
exec sp_configure 'Ad Hoc Distributed Queries',0
reconfigure
exec sp_configure 'show advanced options',0
reconfigure
SELECT *
FROM OPENDATASOURCE(
'SQLOLEDB',
'Data Source=ServerName;User ID=sa;Password=sa'
).DataBaseName.dbo.Table
引用: http://www.cnblogs.com/lhuser/articles/1487947.html
使用OpenRowSet操作Excel Excel导入数据库的更多相关文章
- 使用python将excel数据导入数据库
使用python将excel数据导入数据库 因为需要对数据处理,将excel数据导入到数据库,记录一下过程. 使用到的库:xlrd 和 pymysql (如果需要写到excel可以使用xlwt) 直接 ...
- [Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!
引言 项目中常用到将数据导入Excel,将Excel中的数据导入数据库的功能,曾经也查找过相关的内容,将曾经用过的方案总结一下. 方案一 NPOI NPOI 是 POI 项目的 .NET 版本.POI ...
- 转:[Asp.net]常见数据导入Excel,Excel数据导入数据库解决方案,总有一款适合你!
引言 项目中常用到将数据导入Excel,将Excel中的数据导入数据库的功能,曾经也查找过相关的内容,将曾经用过的方案总结一下. 方案一 NPOI NPOI 是 POI 项目的 .NET 版本.POI ...
- C#解决从含身份证号码的Excel表格导入数据库的问题
用C#做从Excel表导入SQL数据库时发现从EXCEL导入的身份证号码会变成科学表示方法. 解决这个问题是比较容易的,首先,打开电子表格,选中“身份证号码”一列,右键选择“设置单元格格式”,进入单元 ...
- 如何把excel数据导入数据库
这里介绍2种把excel数据导入oracle数据库的方法. 1. 在excel中生成sql语句. 1)在数据列的右侧,第一行的任何位置输入="insert into table(xx,yyy ...
- C#将Excel数据导入数据库(MySQL或Sql Server)
最近一直很忙,很久没写博客了.今天给大家讲解一下如何用C#将Excel数据导入Excel,同时在文章最后附上如何用sqlserver和mysql工具导入数据. 导入过程大致分为两步: 1.将excel ...
- Excel数据导入数据库
maven依赖 <!--excel相关依赖--> <dependency> <groupId>org.apache.poi</groupId> < ...
- 利用poi,jxl将Excel数据导入数据库
需求:‘需要将本地的Excel中的数据经过验证之后导入数据库,在导入数据库之前在页面上展示出来 思路:将Excel导入存到session里面 去判断有没有不合法数据 如果有阻止提交 工具类: imp ...
- PHPExcel将Excel数据导入数据库
<?php //PHPExcel读取导入Excel数据到数据库(2003,2007通用)使用方法: //先用excel2array()方法将excel表中的数据存储到数组,在从遍历二维数组将数据 ...
- NPOI操作之一EXCEL数据导入数据库
一.概要 前面讲到NPOI操作EXCEL导出功能,下面讲下从EXCEL里获取数据添加进数据库. 二.代码 HSSFWorkbook hssfworkbook; public void ExcelDat ...
随机推荐
- C语言 · 贪心算法
发现蓝桥杯上好多题目涉及到贪心,决定学一学. 贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说:不从整体最优上考虑,而是在某种意义上的局部最优解.其关键是贪心策略的选择,选择的贪心 ...
- Linux 进程间通信(posix消息队列 简单)实例
Linux 进程间通信(posix消息队列 简单)实例 详情见: http://www.linuxidc.com/Linux/2011-10/44828.htm 编译: gcc -o consumer ...
- IOS中摇一摇实现截屏(可实现问题反馈的功能)
有一段时间没有更新博客了,今天更新一篇关于最近工作中用到的一个功能,先简单描述一下:我们知道,测试人员在测试客户端产品时,当出现问题或者BUG的时候,都得先对页面截图,然后从相册中选择截图,加上一段描 ...
- Codeforces 558C Amr and Chemistry 暴力 - -
点击打开链接 Amr and Chemistry time limit per test 1 second memory limit per test 256 megabytes input stan ...
- 教你如何做一个优雅的Ecmascripter /转
看看这些被同事喷的JS代码风格你写过多少 殷荣桧 JavaScript 今天 现在写代码比以前好多了,代码的格式都有eslint,prettier,babel(写新版语法)这些来保证,然而,技术手段再 ...
- Java LinkedHashMap工作原理及实现
Java LinkedHashMap工作原理及实现 原文出处: Yikun 1. 概述 在理解了#7 介绍的HashMap后,我们来学习LinkedHashMap的工作原理及实现.首先还是类似的,我们 ...
- 解析xml的4种方法详解
1. 介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许 ...
- 【Spark】RDD机制实现模型
RDD渊源 弹性分布式数据集(RDD).它是MapReduce模型一种简单的扩展和延伸.RDD为了实现迭代.交互性和流查询等功能,须要保证RDD具备在并行计算阶段之间能够高效地数据共享的功能特性.RD ...
- 转载:15个最受欢迎的Python开源框架
出自:http://python.jobbole.com/72306/?replytocom=57112 15个最受欢迎的Python开源框架 Django: Python Web应用开发框架 Dja ...
- 内网DNS投毒技术劫持会话
工具列表: tcpdump Ferret Hamster node closurether 拓扑环境: 攻击机:Kali 10.10.10.237 被攻击机: win7 10.10.10.232 因为 ...