行集函數:OpenRowSet 和 OpenQuery

在SQL Server中,行集函數是不肯定性的,這意味着,每次調用,返回值不老是相同的。返回值是不肯定的,這意味着,對於相同的輸入值,不保證每次返回的值都是相同的。對行集函數的每次調用,行集函數都是單獨計算。行集函數:OpenRowSet 和 OpenQuery 的行爲和Base Table類似:html

  • 可以用於From子句,就像行集函數是一個Base Table,從行集函數中獲取數據;
  • 可以用於修改數據,修改命令(INSERT, UPDATE, or DELETE)直接做用於行集函數,對Base Table進行數據修改;

行集函數:OpenRowSet 語法sql

OPENROWSET 
( { 'provider_name' 
  ,{ 'datasource' ; 'user_id' ; 'password' | 'provider_string' } ,{ [ catalog. ][ schema. ]object | 'query' } } )

‘Provider_name’ 參數:本文主要從SQL Server和Excel中訪問數據,提供程序的名字分別是:SQLNCLI 和 Microsoft.ACE.OLEDB.12.0(處理 .xlsx文件);數據庫

'query' 參數:指定一個穿透查詢(Pass-Through Query)字符串,本地的SQL Server實例不會處理該查詢,在提供程序(Provider)中執行,並返回查詢的結果;ide

一,默認狀況下,OpenRowSet 是Disable狀態函數

OpenRowSet函數可以用於從OLEDB數據源訪問遠程數據的條件是:性能

  • 對於指定提供程序(Provider),DisallowAdhocAccess 註冊表選項顯式設置爲0;
  • 啓用 Ad Hoc Distributed Queries 高級選項,在SQL Server中,該選項默認是Disable的,須要顯式啓用(Enable);

OPENROWSET can be used to access remote data from OLE DB data sources only when the DisallowAdhocAccess registry option is explicitly set to 0 for the specified provider, and the Ad Hoc Distributed Queries advanced configuration option is enabled. When these options are not set, the default behavior does not allow for ad hoc access.this

在SQL Server中啓用 「Ad Hoc Distributed Queries」 高級選項的腳本是:spa

-- enable
exec sp_configure 'show advanced options', 1;
RECONFIGURE;
exec  sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO
--disable
exec sp_configure 'show advanced options', 1;
RECONFIGURE;
exec  sp_configure 'Ad Hoc Distributed Queries', 0;
RECONFIGURE;
GO

若是沒有啓用「Ad Hoc Distributed Queries」 高級選項,在執行OpenRowSet函數時,SQL Server會拋出錯誤信息:操作系統

SQL Server blocked access to STATEMENT 'OpenRowset/OpenDatasource' of component 'Ad Hoc Distributed Queries' because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Ad Hoc Distributed Queries' by using sp_configure. For more information about enabling 'Ad Hoc Distributed Queries', search for 'Ad Hoc Distributed Queries' in SQL Server Books Online.excel

二,從SQL Server 中獲取數據,'provider_name' 參數是 SQLNCLI .

1,使用OpenRowSet 執行 sql 查詢語句,查詢語句被髮送到指定的Server上執行,將結果集返回到OpenRowSet 函數中。Query Statement 使用 Three-Part命名規則,即 Database_Name.Schema_Name.Table_Name。

select *
FROM OPENROWSET(
    'SQLNCLI', 
    'Server=Server_Name;Trusted_Connection=yes;',
    'select * from db_study.dbo.test'  --query statement
) AS t;

2,OpenRowSet 可以在query 子句中,使用 exec 執行存儲過程,返回結果集

SELECT *
FROM OPENROWSET(
    'SQLNCLI', 
    'Server=Server_Name;Trusted_Connection=yes;',
    'exec db_study.[dbo].[usp_test]'  --query statement
) AS t;

三,從Excel中讀取數據,把Excel做爲數據源

從Excel中讀取數據,'provider_name' 是Excel處理引擎的名字,主要有兩個版本:

  • 'Microsoft.Jet.OLEDB.4.0' :用於處理xls文件
  • 'Microsoft.ACE.OLEDB.12.0':用於處理xlsx文件,用於從Microsoft Office Excel 2007中訪問數據

1,註冊'Microsoft.ACE.OLEDB.12.0'引擎

查看SQL Server 可用的Providers,依次點擊 Server Objects-》Linked Servers-》Providers,若是存在Microsoft.ACE.OLEDB.12.0 或 Microsoft.ACE.OLEDB.16.0,說明ACE.OLEDB 引擎已經註冊到系統中,在SQL Server可以執行OpenRowSet函數處理xlsx數據。

若是沒有註冊 'Microsoft.ACE.OLEDB.12.0'引擎,在從Excel中讀取數據時,SQL Server會報錯:The OLE DB provider "Microsoft.ACE.OLEDB.12.0" has not been registered.

註冊ACE OLE DB處理引擎的過程十分簡單,從微軟的官方站點下載:Microsoft Access Database Engine 2010 Redistributable,在安裝驅動程序時,須要匹配機器的系統類型,若是安裝的是是64位操做系統,請安裝:AccessDatabaseEngine_X64.exe,若是遇到:未在本地計算機上註冊「Microsoft.ACE.OLEDB.12.0」提供程序的錯誤,首先檢查系統是否安裝Excel數據庫引擎,而後檢查Excel數據引擎是否和本地的操做系統兼容,請在64位的機器上安裝64位版本的Excel數據庫引擎。

2,配置Excel引擎

在安裝Excel處理引擎以後,在SQL Server中,須要配置AllowInProcess 和 DynamicParameters兩個選項,不然SQL Server會拋出錯誤信息:

OLE DB provider 'Microsoft.ACE.OLEDB.12.0' cannot be used for distributed queries because the provider is configured to run in single-threaded apartment mode.」

EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1 

3,使用OpenRowSet從Excel中查詢數據

使用OpenRowSet從Excel中讀取數據,有兩種格式:使用查詢語句,使用sheet name,例如:

select * 
from OpenRowSet(
    'Microsoft.ACE.OLEDB.12.0', 
    'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\test.xlsx', 
    'select * from [sheet1$]'
) 
--or 
select * 
from OpenRowSet
(
    'Microsoft.ACE.OLEDB.12.0', 
    'Excel 12.0;HDR=Yes;IMEX=1;Database=D:\test.xlsx', 
    [sheet1$]
) 

4,故障排除

在使用OpenRowSet時,常常會遇到如下錯誤消息:

OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "Unspecified error".

Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".

這兩種狀況是因爲權限不夠致使,使用sa帳號登錄,賦予sysadmin 權限便可;

引用《Using OPENROWSET instead of a Linked Server

Windows Authentication            

select a.* from openrowset('SQLNCLI', 'Server=MYINSTANCE;Trusted_Connection=yes;', 'select * from sys.databases') as a

SQL Server Authentication

select a.* from openrowset('SQLNCLI', 'Server=MYINSTANCE;UID=mySQLUser; PWD=*******;', 'select * from sys.databases') as a

行集函數:OpenQuery  語法

OpenQuery在特定的Linked Server上執行穿透查詢,即,OpenQuery函數將查詢語句發送到Remote Server上運行,而後返回查詢結果,大幅提升了Linked Server的查詢性能。(Executes the specified pass-through query on the specified linked server.) 

OPENQUERY ( linked_server ,'query' )

1,Executing an UPDATE pass-through query

UPDATE OPENQUERY (OracleSvr, 'SELECT name FROM joe.titles WHERE id = 101') 
SET name = 'ADifferentName';

2,Executing an INSERT pass-through query

INSERT OPENQUERY (OracleSvr, 'SELECT name FROM joe.titles')
VALUES ('NewTitle');

3,Executing a DELETE pass-through query

DELETE OPENQUERY (OracleSvr, 'SELECT name FROM joe.titles WHERE name = ''NewTitle''');

 

參考doc:

OPENROWSET (Transact-SQL) 

Excel Import to SQL Server using Distributed Queries

MS SQL SERVER READ EXCEL FILE (EXCEL 2010, 2013) - OPENROWSET (x64) - (T-SQL)

OPENQUERY (Transact-SQL)

Top 3 Performance Killers For Linked Server Queries

相關文章
相關標籤/搜索