Problem
I need multiple and repeated queries pulling data from Excel (ie I want query, not import). Excel workbook has multiple worksheets/tabs containing tables/named ranges. My solution already works with MS Access, but I am trying to get it to work with SQL Server. I see this has been asked several times previously, but I haven't been able to get it to work.
In the prototyping below, Excel file is Spread1.xlsm; one tab is named "Datasource". I created database "ExcelProto" for prototyping.
The two references listed below seem relevant. I have tried both the described ad hoc queries approach, and the linked server approach but both fail in a similar way. My adapted code:
First Approach: Linked Server prototype
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$]');
In this prototype code, I first dropped the linked server created in the previous execution attempt as you see; it couldn't be initialized anyway.
Linked Server Error Behavior and messages
ACE shows properly in the Providers tree. Code steps through properly into sp_addLinkedServer, arguments are properly evaluated and sp_addLinkedServer internal statements appear to execute properly. But on sp_addLinkedServer exit, execution stops and an error message is displayed:
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".
Second Approach: Ad Hoc Query prototype Ad Hoc Query setup
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
Setup messages
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.
Query
SELECT * FROM
OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0 Macro;Database=C:\TestProgs\Spread1.xlsm;HDR=YES', 'SELECT * FROM [Datasource$]');
Query messages
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)".
Questions
Same or similar error for both approaches. See any problem with my code adaptations? If the code looks okay, could the issue be assignment of permissions or roles and if so to what entities? Could it be limitations in Express? The references use ACE, but Microsoft docs refer to Jet for Excel... does ACE really work for Excel in SQL Server 2017? Is there a Jet for 2017?
Configuration
- Windows 10 Pro x64. I am Admin.
- SQL Server Express 2017 x64, SSMS 17.3
- Installed Microsoft Access Database Engine 2010 Redistributable referenced in Links
- Office 365 / (Excel 2016) 32-bit
References
How Do I Configure an Excel File as a Linked Server in SQL Server
Import Excel 2010 Into SQL Server
Access Database Engine Redistributable
** 27 Oct Update
Code for OPENROWSET and Linked Server, showing registration and initialization steps: **
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
Took sp_MSset_oledb_prop from master.sys instead of master.dbo, hope that is okay; they do execute properly.
Linked Server and 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$]');
Registrations and initializations in place.
Access Database Engine 2010 was installed, no errors on install. Registry entries are correct for Microsoft.ACE.OLEDB.12.0, at Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL14.SQLEXPRESS\Providers\Microsoft.ACE.OLEDB.12.0
However, both OPENROWSET and Linked Server approach result in messages
OPENROWSET:
Msg 7303, Level 16, State 1, Line 27
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
Linked Server:
Msg 7303, Level 16, State 1, Line 44
Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "ExcelLink".
So neither can initialize Microsoft.ACE.OLEDB.12.0.
Altho no errors on install of Access Database Engine 2010, the Office 365 installation is 32-bit (MS recommended config!). Before I re-install that, I am going to try the latest SQL above on a machine with no Office installation at all.