【发布时间】:2017-10-10 17:44:54
【问题描述】:
问题
我需要从 Excel 中提取数据的多个重复查询(即我想要查询,而不是导入)。 Excel 工作簿有多个包含表格/命名范围的工作表/选项卡。我的解决方案已经适用于 MS Access,但我正试图让它与 SQL Server 一起使用。我看到这个问题已经被问过好几次了,但我一直没能让它工作。
在下面的原型中,Excel文件是Spread1.xlsm;一个选项卡名为“数据源”。我为原型设计创建了数据库“ExcelProto”。
下面列出的两个参考资料似乎相关。我已经尝试过描述的 ad hoc query 方法和 linked server 方法,但都以类似的方式失败。我改编的代码:
第一种方法:链接服务器原型
USE ExcelLink
GO
EXEC sp_dropserver
@server= 'ExcelLink',
@droplogins= 'droplogins';
GO
EXEC sp_addLinkedServer
@server= N'ExcelLink',
@srvproduct= N'ACE 12.0',
@provider= N'Microsoft.ACE.OLEDB.12.0',
@datasrc= N'C:\TestProgs\Spread1.xlsm',
@location= NULL,
@provstr= N'Excel 12.0 Macro;HDR=YES',
@catalog= NULL;
GO
SELECT * FROM OPENQUERY (ExcelLink, 'Select * from [Datasource$]');
在这个原型代码中,我首先删除了在之前的执行尝试中创建的链接服务器,如您所见;无论如何都无法初始化。
链接服务器错误行为和消息
ACE 在提供者树中正确显示。代码正确进入 sp_addLinkedServer,参数被正确评估,并且 sp_addLinkedServer 内部语句似乎正确执行。但在 sp_addLinkedServer 退出时,执行停止并显示错误消息:
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "ExcelLink" returned message "Unspecified error".
Msg 7303, Level 16, State 1, Line 19
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "ExcelLink".
第二种方法:即席查询原型 即席查询设置
USE ExcelProto
GO
sp_configure 'show advanced options', 1
GO
RECONFIGURE WITH OverRide
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE WITH OverRide
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
GO
设置消息
Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
Configuration option 'Ad Hoc Distributed Queries' changed from 1 to 1. Run the RECONFIGURE statement to install.
查询
SELECT * FROM
OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0 Macro;Database=C:\TestProgs\Spread1.xlsm;HDR=YES', 'SELECT * FROM [Datasource$]');
查询消息
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "Unspecified error".
Msg 7303, Level 16, State 1, Line 1
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
问题
两种方法的错误相同或相似。看到我的代码改编有任何问题吗?如果代码看起来没问题,问题可能是权限或角色的分配,如果是,分配给哪些实体?会不会是 Express 的限制?引用使用 ACE,但 Microsoft 文档引用 Jet for Excel...ACE 真的适用于 SQL Server 2017 中的 Excel 吗? 2017 年有喷气机吗?
配置
- Windows 10 专业版 x64。我是管理员。
- SQL Server Express 2017 x64,SSMS 17.3
- 已安装 Microsoft Access 数据库引擎 2010 Redistributable 链接中引用
- Office 365 / (Excel 2016) 32 位
参考文献
How Do I Configure an Excel File as a Linked Server in SQL Server
Import Excel 2010 Into SQL Server
Access Database Engine Redistributable
** 10 月 27 日更新
OPENROWSET 和 Linked Server 的代码,显示注册和初始化步骤:**
OPENROWSET
USE ExcelProto
GO
/* Configure OLEDB */
sp_configure
@configname='Show Advanced Options',
@configvalue=1;
RECONFIGURE WITH OverRide;
GO
sp_configure
@configname='Ad Hoc Distributed Queries',
@configvalue=1;
RECONFIGURE WITH OverRide;
GO
EXEC master.sys.sp_MSset_oledb_prop
@provider_name=N'Microsoft.ACE.OLEDB.12.0',
@property_name=N'AllowInProcess',
@property_value=1;
GO
EXEC master.sys.sp_MSset_oledb_prop
@provider_name=N'Microsoft.ACE.OLEDB.12.0',
@property_name=N'DynamicParameters',
@property_value=1;
GO
/* Pull in each Excel worksheet/table */
SELECT * FROM OPENROWSET(
N'Microsoft.ACE.OLEDB.12.0',
N'Excel 12.0 Xml; Database=C:\TestProgs\Spread3.xlsx; HDR=YES; IMEX=1',
'SELECT * FROM [Datasource$]'
);
GO
从master.sys而不是master.dbo中获取sp_MSset_oledb_prop,希望没问题;它们确实执行正确。
链接服务器和OPENQUERY
USE ExcelProto
GO
/* Configure OLEDB */
sp_configure
@configname='Show Advanced Options',
@configvalue=1;
RECONFIGURE WITH OverRide;
GO
sp_configure
@configname='Ad Hoc Distributed Queries',
@configvalue=1;
RECONFIGURE WITH OverRide;
GO
EXEC master.sys.sp_MSset_oledb_prop
@provider_name=N'Microsoft.ACE.OLEDB.12.0',
@property_name=N'AllowInProcess',
@property_value=1;
GO
EXEC master.sys.sp_MSset_oledb_prop
@provider_name=N'Microsoft.ACE.OLEDB.12.0',
@property_name=N'DynamicParameters',
@property_value=1;
GO
/* Delete prior instances of Linked Server to each worksheet/table */
EXEC sp_dropserver
@server= 'ExcelLink',
@droplogins= 'droplogins';
GO
/* Create a Linked Server to each Excel worksheet/table */
EXEC sp_addLinkedServer
@server= N'ExcelLink',
@srvproduct= N'Excel',
@provider= N'Microsoft.ACE.OLEDB.12.0',
@datasrc= N'C:\TestProgs\Spread3.xlsx',
@location= NULL,
@provstr= 'Excel 12.0 Xml;HDR=YES;IMEX=1;',
@catalog= NULL;
GO
/* Pull in each Excel worksheet/table */
SELECT * FROM OPENQUERY (ExcelLink, 'Select * from [Sheet1$]');
注册和初始化到位。
Access Database Engine 2010 已安装,安装时没有错误。 Microsoft.ACE.OLEDB.12.0 的注册表项是正确的,位于 Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.SQLEXPRESS\Providers\Microsoft.ACE.OLEDB.12.0
但是,OPENROWSET 和链接服务器方法都会产生消息
开放式:
消息 7303,第 16 层,状态 1,第 27 行
无法为链接服务器“(null)”初始化 OLE DB 提供程序“Microsoft.ACE.OLEDB.12.0”的数据源对象。
链接服务器:
消息 7303,第 16 级,状态 1,第 44 行
无法为链接服务器“ExcelLink”初始化 OLE DB 提供程序“Microsoft.ACE.OLEDB.12.0”的数据源对象。
因此两者都无法初始化 Microsoft.ACE.OLEDB.12.0。
尽管 Access Database Engine 2010 安装没有错误,Office 365 安装是 32 位(MS 推荐配置!)。在我重新安装之前,我将在根本没有安装 Office 的机器上尝试上面的最新 SQL。
【问题讨论】:
-
这应该会回答您关于驱动程序之间差异的问题(基本上 ACE 较新且支持 64 位):stackoverflow.com/questions/14401729/…
-
还注意到您的“数据库”是一个 XLSM 文件。不是 XLS 或 XLSX。这可能是问题所在。我从未尝试过用这种方法查询 XLSM。尝试使用空白的 XLSX 文件,看看是否有相同的错误?
-
最后,也许在你的连接字符串属性中尝试 IMEX=1:stackoverflow.com/questions/10102149/…
-
感谢 JacobH。与空白 .xlsx 相同的结果(将文件类型更改为“Excel 12.0 Xml”,也尝试了 Excel 12.0),并尝试了 IMEX=1,同时 HDR=NO 和 HDR=YES... 仍然无法初始化数据源对象OLE DB 提供程序。
-
嗯...也许 x86 与 x64 版本的 ACE 驱动程序?也许它是像这篇文章一样的文件权限:blog.sqlauthority.com/2016/12/31/…
标签: sql-server excel sql-server-express linked-server