2017-10-10 109 views
0

問題從Excel工作表標籤中提取數據到SQL Server

我需要多次反覆查詢從Excel中提取數據(即我想查詢,而不是進口)。 Excel工作簿具有多個包含表格/命名區域的工作表/選項卡。我的解決方案已經適用於MS Access,但我試圖讓它與SQL Server一起工作。我看到這個問題以前曾被多次提出過,但是我一直沒有能夠實現。

在下面的原型中,Excel文件是Spread1.xlsm;一個選項卡被命名爲「數據源」。我爲原型創建了數據庫「ExcelProto」。

下面列出的兩個參考文獻似乎相關。我已經嘗試了描述的即席查詢方法和鏈接服務器方法,但都以類似的方式失敗。我適應代碼:

第一種方法:鏈接服務器原型

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年有沒有Jet?

配置

  • 的Windows 10專業版64位。我是管理員。
  • 的SQL Server Express 2017年的x64,SSMS 17.3
  • 安裝Microsoft Access數據庫引擎2010可再發行 在鏈接引用
  • 的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和鏈接服務器,顯示註冊和初始化步驟:**

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 

拿了sp_MSset_oledb_prop從master.sys代替master.dbo,希望沒關係;他們確實執行正確。

鏈接服務器和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數據庫引擎2010已安裝,沒有安裝錯誤。註冊表項是正確的Microsoft.ACE.OLEDB.12.0,在Computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL Server \ MSSQL14.SQLEXPRESS \ Providers \ Microsoft.ACE.OLEDB.12.0

但是,OPENROWSET和鏈接服務器方法導致消息
OPENROWSET:
Msg 7303,級別16,狀態1,行27 無法初始化鏈接服務器「(null)」的OLE DB提供程序「Microsoft.ACE.OLEDB.12.0」的數據源對象。

鏈接服務器:
消息7303,級別16,狀態1,線44 無法初始化OLE DB提供程序 「Microsoft.ACE.OLEDB.12.0」 鏈接服務器 「EXCELLINK」 的數據源對象。

因此,既不能初始化Microsoft.ACE.OLEDB.12.0。

雖然安裝Access數據庫引擎2010時沒有錯誤,Office 365安裝是32位(MS推薦配置!)。在重新安裝之前,我將在沒有安裝Office的計算機上嘗試使用上述最新的SQL。

+0

這應該回答有關驅動程序(基本上ACE是新的和64位支持)之間的差異問題:https://stackoverflow.com/questions/14401729/difference-between-microsoft-jet-oledb-和-microsoft-ace-oledb –

+0

也注意到你的「數據庫」是一個XLSM文件。不是XLS或XLSX。這可能是問題。我從來沒有試過用這種方法來查詢XLSM。嘗試使用空白的XLSX文件,看看你是否也有相同的錯誤? –

+0

最後,也許你的連接字符串屬性嘗試IMEX = 1:https://stackoverflow.com/questions/10102149/what-is-imex-in-the-oledb-connection-string –

回答

0

你可以這樣試試嗎?

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

OR

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/

而且,我知道這裏的人不喜歡貼ONLY聯繫,所以我會添加從上面列出的網站一些更多的信息。

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 
+0

感謝您的回答和鏈接。 - OPENROWSET和OPENDATASOURCE均返回 消息7303,級別16,狀態1,行24 無法初始化鏈接服務器「(null)」的OLE DB提供程序「Microsoft.ACE.OLEDB.12.0」的數據源對象。 --Example我的實現的: SELECT * FROM OPENROWSET( 'Microsoft.ACE.OLEDB.12.0', 'Excel的12.0的Xml; 數據庫= C:\ TestProgs \ Spread3.xlsx',[數據源$]); - 我的配置:SQL Server Express x64,ACE x64; Office365 x86:ACE安裝問題?在SSMS中顯示好。 – netboyz

+0

我剛更新了我的帖子。我無法測試它現在的位置,但試試我剛纔建議的內容,看看它是否適合你。 – ryguy72

+0

再次感謝您的輸入和鏈接。我還發現http://searchsqlserver.techtarget。com/tip/Using-the-OPENROWSET-function-in-SQL-Server,全部使用相同的波長。更新了原始帖子,標記爲27 10月:進行了所有SQL更新,但仍然存在初始化錯誤。此機器具有32位Office,因此將在沒有安裝Office的計算機上重新嘗試代碼。 – netboyz

相關問題