【问题标题】:Pulling data from Excel worksheet tab into SQL Server将 Excel 工作表选项卡中的数据拉入 SQL Server
【发布时间】: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


【解决方案1】:

你可以这样试试吗?

SELECT * 
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
  'Excel 12.0 Xml;
   Database=C:\DataFiles\EmployeeData1.xlsx',
   [vEmployee$]); 

SELECT * 
FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0',
  'Data Source=C:\DataFiles\EmployeeData1.xlsx;
   Extended Properties=Excel 12.0 Xml')...[vEmployee$]

;

带标题:

SELECT * 
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
  'Excel 12.0 Xml; HDR=YES;
   Database=C:\DataFiles\EmployeeData1.xlsx',
   [vEmployee$]);

没有标题:

SELECT * 
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
  'Excel 12.0 Xml; HDR=NO;
   Database=C:\DataFiles\EmployeeData1.xlsx',
   [vEmployee$]);

https://www.red-gate.com/simple-talk/sql/t-sql-programming/questions-about-using-tsql-to-import-excel-data-you-were-too-shy-to-ask/

我在这里更新我原来的帖子。 . .

查看此链接:

https://sqlwithmanoj.com/2012/07/10/querying-excel-2010-from-sql-server-in-64-bit-environment/

另外,我知道这里的人不喜欢只发布链接,所以我会从上面列出的网站添加更多信息。

So let’s first of all enable this:


USE [MSDB]
GO

sp_configure 'show advanced options', 1
GO
RECONFIGURE WITH OverRide
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE WITH OverRide
GO

You can also enable this setting graphically by going to “Surface Area Configuration” and enable it.


–> Now, to access the Excel file there are 2 ways:

1. Directly fetch records from Excel by using the OPENROWSET() function by providing the providers and other options

2. Indirectly by creating a Linked Server first of all, then:
2.a. fetching records from Excel by using OPENQUERY() function or
2.b. by using the Linked Server name within the SELECT query


-- 1. Directly, by using OPENROWSET() function
SELECT * FROM OPENROWSET (
    'Microsoft.ACE.OLEDB.12.0',
    'Excel 12.0;Database=E:\SQL Server - Blogs\LinkedServer2010.xlsx;HDR=YES;IMEX=1',
    'SELECT * FROM [Sheet1$]'
);

-- OR --

-- 2. Indirectly, by Creating Linked Server & using OPENQUERY:
EXEC sp_addLinkedServer
    @server= N'XLSX_2010',
    @srvproduct = N'Excel',
    @provider = N'Microsoft.ACE.OLEDB.12.0',
    @datasrc = N'E:\SQL Server - Blogs\LinkedServer2010.xlsx',
    @provstr = N'Excel 12.0; HDR=Yes';
GO

-- 2.a. Using OPENQUERY() function:
SELECT * FROM OPENQUERY (XLSX_2010, 'Select * from [Sheet1$]')

-- 2.b. Using the Linked Server name within the SELECT query:
SELECT * FROM XLSX_2010...[Sheet1$]

I searched on net and I got following solution in MSDN forums to register the ACE OLEDB 12.0 provider:



USE [master]
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

【讨论】:

  • 感谢您的回答和链接。 --OPENROWSET 和 OPENDATASOURCE 都返回 Msg 7303,级别 16,状态 1,第 24 行无法初始化链接服务器“(null)”的 OLE DB 提供程序“Microsoft.ACE.OLEDB.12.0”的数据源对象。 --我的实现示例:SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0 Xml; Database=C:\TestProgs\Spread3.xlsx', [Datasource$]); --我的配置:SQL Server Express x64、ACE x64; Office365 x86:ACE 安装问题?在 SSMS 中显示正常。
  • 我刚刚更新了我的帖子。我现在无法测试它,但试试我刚才的建议,看看是否适合你。
  • 再次感谢您的输入和链接。我还找到了searchsqlserver.techtarget.com/tip/…,都在同一个波长上。更新了原始帖子,标记为 10 月 27 日:所有 SQL 更新完成,但仍然初始化错误。这台机器有 32 位 Office,因此将在根本没有安装 Office 的机器上重试代码。
猜你喜欢
  • 2020-06-02
  • 2012-09-14
  • 2012-11-23
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多