SQL調用另一台服務器的表及存儲過程(SQL函數openrowset()的使用以及相關問題處理)


--查詢表
select * from openrowset('SQLOLEDB', 'IP'; 'sa'; '密碼',數據庫名稱.dbo.表名稱)

--查詢存儲
--示例1
select * from openrowset('SQLOLEDB', 'SERVER=IP;uid=sa;pwd=密碼;Database=數據庫名稱','SET FMTONLY OFF;SET NOCOUNT ON exec 存儲過程名稱 ''165'' ,''2019-11-23'' ,''''')

--示例2
select * from openrowset('SQLOLEDB', 'SERVER=IP;uid=sa;pwd=密碼;Database=數據庫名稱','SET FMTONLY OFF;SET NOCOUNT ON exec 存儲過程名稱 ''162'' ,''2019-11-23'' ,''''')

 

 

你可能常常會需要運行一個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腳本:
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從句里使用。下面的例子顯示了該函數的基本語法:
OPENROWSET('provider', 'connection string', target) 

  可以看到,這個函數有三個參數: 
  •provider —— 某特定數據源支持的OLE DB提供者的人機友好名稱(ProgID)。Provider的名字必須用單引號括起來。
  •Connection string —— 連接串。它是與具體提供者provider相關的字符串,包括連接到給字符串中指定的數據源所需要的細節信息。根據provider的不同,連接串信息需要用一對或多對單引號括起來。
  •Target —— target參數可以使一個數據庫對象或者一個查詢。
  Object —— 數據庫對象的名字,比如表或者視圖的名稱。對象的完整名字必須提供,它們不需要用單引號括起來。
  Query —— query是從遠程數據源提取數據的Select語句。Query必須用單引號括起來。
  下面的例子展示了OPENROWSET函數的用法:
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表。
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數據庫查詢數據。
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並導入數據。
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文件作為二進制數據批量導入到該列。
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函數批量導入數據功能時,你也可以使用格式化的文件,不過關於格式化文件的用法超出了本文討論的范圍。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM