使用SQL Server的OPENROWSET函數

 你可能常常會需要運行一個ad hoc查詢從遠程OLE DB數據源提取數據,或者批量向SQL Server表導入數據。在這種情況下,你可以在T-SQL(Transact-SQL,微軟對SQL的擴展)中用OPENROWSET函數給數據源傳入一個連接串和查詢來提取需要的數據。

  你可能常常會需要運行一個ad hoc查詢從遠程OLE DB數據源提取數據,或者批量向SQL Server表導入數據。在這種情況下,你可以在T-SQL(Transact-SQL,微軟對SQL的擴展)中用OPENROWSET函數給數據源傳入一個連接串和查詢來提取需要的數據。

  你可以使用OPENROWSET函數從任何支持註冊OLE DB的數據源獲取數據,比如從SQL Server或Access的遠程實例中提取數據。如果你用OPENROWSET從SQL Server實例中獲取數據,該實例必須配置爲允許ad hoc分佈式查詢。

  要配置遠程SQL Server實例支持ad hoc查詢,需要使用系統存儲過程sp_configure先設置advanced options,再啓用Ad Hoc Distributed Queries(ad hoc分佈式查詢)。請看下面的T-SQL腳本:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  EXEC sp_configure 'show advanced options', 1;

  
GO

  
RECONFIGURE;

  
GO

  
EXEC sp_configure 'Ad Hoc Distributed Queries', 1

  
GO

  
RECONFIGURE;

  
GO

   要注意的是,在運行完存儲過程之後,你必須運行“RECONFIGURE”命令。 一旦你配置好了遠程SQL Server實例,你就可以對它使用OPENROWSET函數。這個函數可以在SELECT語句的FROM從句裏使用。下面的例子顯示了該函數的基本語法:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  OPENROWSET('provider', 'connection string', target)

   可以看到,這個函數有三個參數:

  ·Provider —— 某特定數據源支持的OLE DB提供者的人機友好名稱(ProgID)。Provider的名字必須用單引號括起來。

  ·Connection string —— 連接串。它是與具體提供者provider相關的字符串,包括連接到給字符串中指定的數據源所需要的細節信息。根據provider的不同,連接串信息需要用一對或多對單引號括起來。

  ·Target —— target參數可以使一個數據庫對象或者一個查詢。

  ·Object —— 數據庫對象的名字,比如表或者視圖的名稱。對象的完整名字必須提供,它們不需要用單引號括起來。

  ·Query —— query是從遠程數據源提取數據的Select語句。Query必須用單引號括起來。

  下面的例子展示了OPENROWSET函數的用法:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  SELECT Employees.*

  
FROM OPENROWSET(

  
'SQLNCLI',

  
'Server=SqlSrv1;Trusted_Connection=yes',

  
'SELECT EmployeeID, FirstName, LastName, JobTitle

  FROM AdventureWorks.HumanResources.vEmployee

  ORDER BY LastName, FirstName
'

  )
AS Employees

   注意該Select語句的FROM從句中使用了OPENROWSET函數和3個參數。第一個參數SQLNCLI是SQL Server OLE DB提供者的名稱。

  第二個參數是連接串。對於SQL Server提供者,整個連接串應該被單引號括起來,連接串內的每一組信息用分號分割。在上面的例子中,第一組信息指定了目標服務器SqlSrv1,第二組信息指定了該連接可信任連接。在指定目標Server時,如果實例不是該Server的默認實例,則一定要在連接串中指定實例名。(注意:SQLNCLI提供者還支持其他參數。)

  OPENROWSET函數的最後一個參數是實際執行的Select語句。注意SQL語句中使用了完整對象名來訪問視圖。

  這樣我們就可以使用OPENROWSET函數了。函數返回一個結果集(我把它用AS命名爲“Employees”),From使用該結果集的方式與使用其他普通查詢的方式一樣。 我們在上面提到,你也可以從SQL Server以外的數據源提取數據。例如:下面的Select語句查詢微軟Access數據庫的Employees表。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  SELECT Employees.*

  
FROM OPENROWSET(

  
'Microsoft.Jet.OLEDB.4.0',

  
'C:/Data/Employees.mdb';'admin';' ',

  
'SELECT EmployeeID, FirstName, LastName, JobTitle

  FROM Employees

  ORDER BY LastName, FirstName
'

  )
AS Employees

   你可能注意到了,這次的provider不同於我們在訪問SQL Server時使用的Provider。在本例中,Provider是Microsoft.Jet.OLEDB.4.0(注意:對於Access 2007,有新的Provider可用)。

  連接串與前面例子中的寫法也不一樣。整個連接串從頭到尾分成了三部分,每一部分都被單引號單獨括起來,各部分之間用分號分割。

  第一部分指定了Access數據庫文件的路徑和文件名,後面緊跟着是用戶賬號admin(Access數據庫內部的管理員賬號)。第三部分是一個空字符串,是Access數據庫的密碼。因爲admin賬號沒有設定密碼,所以使用空字符串。如果該賬號設置了密碼,應該把密碼寫在第三部分。

  整個連接串與後面用來從Access數據庫查詢數據的Select語句用逗號“,”隔開。(我在Access中使用的Employees表是從SQL Server的vEmployee視圖導入的) 這就是從Access數據庫查詢數據要做的全部事情。你的查詢會返回一個結果集,該結果集與訪問本地SQL Server數據庫時得到的結果集類似。

  你也可以使用OPENROWSET函數從多個數據源中查詢數據。例如:下面的例子我使用inner join(內連接)從遠程SQL Server實例和Access數據庫查詢數據。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  SELECT e1.EmployeeID, e2.FirstName, e2.LastName, e1.JobTitle

  
FROM OPENROWSET(

  
'SQLNCLI',

  
'Server=SqlSrv1;Trusted_Connection=yes;',

  
'SELECT EmployeeID, FirstName, LastName, JobTitle

  FROM AdventureWorks.HumanResources.vEmployee
'

  )
AS e1

  
INNER JOIN OPENROWSET(

  
'Microsoft.Jet.OLEDB.4.0',

  
'C:/Data/Employees.mdb'; 'admin';' ',

  
'SELECT EmployeeID, FirstName, LastName, JobTitle

  FROM Employees
'

  )
AS e2

  
ON e1.EmployeeID = e2.EmployeeID

  
ORDER BY e2.LastName, e2.FirstName

   注意:外層的Select語句從兩個表返回數據——從SQL Server返回員工ID和工作頭銜,從Access數據庫返回姓和名。由於你可以得到可靠的連接查詢,儘管你是從本地SQL Server實例連接表中查詢的數據,你可以處理這些數據。

  現在我們來看看OPENROWSET函數的另一個重要功能——批量導入。爲了舉例需要,我在AdventureWorks數據庫中用下面的腳本創建了表Employees並導入數據。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  USE AdventureWorks

  
GO

  
IF OBJECT_ID (N'Employees', N'U') IS NOT NULL

  
DROP TABLE dbo.Employees

  
GO

  
SELECT EmployeeID, FirstName, LastName, JobTitle

  
INTO Employees

  
FROM HumanResources.vEmployee

  
GO

  
ALTER TABLE Employees

  
ADD ResumeFile VARBINARY(MAX) NULL

  
GO

  注意:我沒有把ResumeFile列的數據導入,它的數據類型是VARBINARY(MAX)。我會用下面的Update語句把Employee1.docx文件作爲二進制數據批量導入到該列。

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  USE AdventureWorks

  
GO

  
UPDATE Employees

  
SET ResumeFile = (

  
SELECT *

  
FROM OPENROWSET(BULK 'C:/Data/Employee1.docx', SINGLE_BLOB)

  
AS ResumeContent)

  
WHERE EmployeeID = 1

  可以看到,OPENROWSET函數提供了BULK選項,你可以用它來導入數據。要使用BULK選項,需要指定你想要導入的文件,並指定導入方式。既然我想把文件以二進制形式導入,我在上面的例子中使用了SINGLE_BLOB選項。當然,如果該列支持字符型數據,我也可以用SINGLE_CLOB或者SINGLE_NCLOB選項指定數據存儲爲字符類型格式。此外,在使用OPENROWSET函數批量導入數據功能時,你也可以使用格式化的文件,不過關於格式化文件的用法超出了本文討論的範圍。

  不管你是否使用OPENROWSET函數批量導入數據或者連接OLE DB數據源,你都會發現用它獲取數據非常方便。關於這個函數的更多細節,請在SQL Server聯機圖書查看標題爲“OPENROWSET (Transact-SQL)”的文章。在那裏你可以看到關於SQLNCLI提供者(或者SQL Server 2008的SQLNCL10提供者)的更多細節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章