分佈式數據庫2005 簡單用法

/*分佈式查詢*/
分佈式查詢(Distributed Query)能夠訪問存放在同一部計算機或不同計算機上的SQL Server或不同種類的數據源。衆所周知,OLE DB是Microsoft規格的公用數據訪問的應用程序開發界面(Application Programming Interface,API),而SQL Server2000即是使用OLE DB來支持分佈式查詢的。
SQL Server2000中提供了兩種方法來實現訪問不同種類的OLE DB數據源:第一,使用“鏈接服務器”(Linked Server);第二,使用“特定名稱”(Ad Hoc Names)。下面,我們將就這兩種方法進行詳細的闡述。
(一) 鏈接服務器
鏈接服務器是一個定義於SQL Server2000中的虛擬服務器,鏈接服務器的名稱是使用系統存儲過程sp_addlinkedserver定義的。
當要處理鏈接服務器中的對象時,必須使用完整的四部分名稱:linked_server_name.catalog.schema.object_name。

說明:
這四部分名稱對應於SQL Server而言,分別是:引用OLE DB數據源的鏈接服務器名稱、數據庫名稱、所有者、數據表或視圖。


注意:SQL Server不支持跨鏈接服務器的全文檢索搜索!


基本上,SQL Server允許您採用如下方式來訪問鏈接服務器中的數據:
a、分佈式查詢。可以在Select、Insert、Update與Delete等T-SQL命令語句中以四部分名稱來訪問鏈接服務器中的數據表或視圖。
b、使用OPENQUERY()函數在鏈接服務器上運行查詢。該函數會將一條命令傳送給鏈接服務器來運行,它返回的行集可以在T-SQL命令
語句中以一個數據表或視圖的形式來使用。
c、遠程存儲過程。可以使用四部分名稱來運行鏈接服務器中的存儲過程。


特別提醒:我們應該將一個經常需要查詢的OLE DB數據源定義成一個鏈接服務器,然而,一個查詢頻率很低的OLE DB數據源將不值得特別爲它定義一個鏈接服務器,此時應該採用特定名稱的方式。


(二) 使用sp_addlinkedserver創建鏈接服務器
sp_addlinkedserver的語法如下所示:
sp_addlinkedserver [@server=] 'server'
[,[@srvproduct=] 'product_name']
[,[@provider=] 'provider_name']
[,[@datasrc=] 'data_source']
[,[@location=] 'location']
[,[@provstr=] 'provider_string']
[,[@catalog=] 'catalog']
各具體參數說明如下:
(1) [@server] 'server'
是指所要創建的鏈接服務器的本地名稱。此名稱不能與已存在的鏈接服務器的名稱相同。同時請注意:如果您並未使用[@datasrc=] 'data_source'參數來賦值OLE DB數據源名稱,則[@server] 'server'必須是OLE DB數據源的名稱。
(2) [@srvproduct=] 'product_name'
是指OLE DB數據源的產品名稱。此參數的數據類型是nvarchar(128),默認值是NULL。
如果OLE DB數據源就是SQL Server,那麼可以使用N'SQL Server'作爲設置值,而且此時不再需要賦值provider_name、data_source、location、provider_string與catalog,不過採用這個方法,[@server] 'server'必須
是SQL Server的網絡名稱(即所在計算機的名稱)。
如果OLE DB數據源是SQL Server之外的數據源,則您可以自定義產品名稱。
說明:如果您所創建的鏈接服務器也是一個SQL Server,則可以運行此鏈接服務器上的存儲過程,即運行
所謂的遠程存儲過程。
(3) [@provider=] 'provider_name'
是指OLE DBProvider的PROGID。
安裝於計算機中的每一個OLE DB Provider都會擁有一個惟一的provider_name。此參數的數據類型是
nvarchar(128),默認值爲NULL。
下面列出了各種OLE DB數據源對應的provider_name:
遠程OLE DB數據源        OLE DB Provider                                Provider_name
SQL Server             Microsoft OLE DB Provider for SQL Server       SQLOLEDB
Access/Jet             Microsoft OLE DB Provider for Jet              Microsoft.Jet.OLEDB.4.0
Microsoft Excel工作簿   Microsoft OLE DB Provider for Jet              Micorsoft.Jet.OLEDB.4.0
文本文件                Microsoft OLE DB Provider for Jet              Micorsoft.Jet.OLEDB.4.0
orACLE                 Microsoft OLE DB Provider for oracle           MSDAORA
IBM DB2數據庫          Microsoft OLE DB Provider for DB2               DB2OLEDB
ODBC數據源             Microsoft OLE DB Provider for ODBC              MSDASQL
文件系統               Microsoft OLE DB Provider for Indexing Service  MSIDXS
(4) [@datasrc=] 'data_source'
是OLE DB Provider所解釋的數據源名稱。此參數的數據類型是nvarchar(128),默認值爲NULL。對不同的
OLE DB Provider而言,數據源所代表的對象與賦值方式也有所不同,請詳見下表所示:
遠程OLE DB數據源      OLE DB Provider                                   data_source
SQL Server            Microsoft OLE DB Provider for SQL Server          所在計算機名稱
Access/Jet            Microsoft OLE DB Provider for Jet                 數據庫文件.mdb的完整路徑與文件名稱
Microsoft Excel工作簿   Microsoft OLE DB Provider for Jet               工作簿.xls的完整路徑與文件名稱
文本文件                Microsoft OLE DB Provider for Jet               文本文件.txt的完整路徑但不含文件名稱
orACLE                 Microsoft OLE DB Provider for oracle             指向某個Oracle數據庫的SQL*Net別名
IBM DB2數據庫          Microsoft OLE DB Provider for DB2                 不需指定,它是通過provider_string來賦值的
ODBC數據源             Microsoft OLE DB Provider for ODBC                如果不採用連接字符串,則爲ODBC數據源的系統DSN,否則不需賦值數據源
文件系統               Microsoft OLE DB Provider for Indexing Service    可以運行屬性搜索或全文檢索的內容文件
(5) [@location=] 'location'
是指由OLE DB Provider所解釋的數據庫位置。此參數的數據類型是nvarchar(4000),默認值爲NULL。
(6) [@provstr=] 'provider_string'
是一個能夠識別惟一數據源的OLE DB Provider連接字符串。此參數的數據類型是nvarchar(128),默認值爲NULL。
並不是所有的OLE DB數據源都需要賦值連接字符串,只有下表中列出的才需要:
遠程OLE DB數據源      OLE DB Provider                                provider_string
Microsoft Excel工作簿   Microsoft OLE DB Provider for Jet            Excel 5.0
文本文件                Microsoft OLE DB Provider for Jet            Text
IBM DB2數據庫          Microsoft OLE DB Provider for DB2             連接字符串
ODBC數據源             Microsoft OLE DB Provider for ODBC            如果不賦值數據源,就必須使用ODBC連接字符串
(7) [@catalog=] 'catalog'
是指當前連接到OLE DBProvider時所使用的目錄。對SQL Server而言,目錄就是指數據庫。

以下,我們將通過數個範例來實際展示如何使用系統存儲過程sp_addlinkedserver創建鏈接服務器,以及如何通過分佈式查詢去
查詢鏈接服務器中的數據表。
/*範例1*/
use master
go
exec sp_addlinkedserver
@server='tpserver',
@srvproduct=N'SQL Server'
go
/*
說明:在本例中,我們直接使用語法中的[@srvproduct=] 'product_name'將產品名稱設置爲N'SQL Server',因此所賦值的鏈接服務器的本地名稱tpserver必須就是所要鏈接的SQL Server的網絡名稱。當然,您也可以將tpserver更改成您網絡上的某一個SQL Server的名稱。
*/
--查詢創建於本地計算機上的各個鏈接服務器
exec sp_linkedservers
go
--刪除鏈接服務器
exec sp_dropserver 'tpserver'

exec sp_dropserver 'tpserver', 'droplogins'

/*範例2*/
use northwind
go
--如果並未賦值數據源,則服務器名稱必須就使所要鏈接的服務器名稱
exec sp_addlinkedserver @server='tpserver',
   @srvproduct=N'SQL Server'
go

--自定義鏈接服務器的名稱,此時必須賦值其他參數
--鏈接服務器MyLinkedServer1的數據源是網絡名稱爲tpserver的SQL Server
exec sp_addlinkedserver @server='mylinkedserver1',
   @srvproduct=N'',
   @provider=N'SQLOLEDB',
   @datasrc=N'tpserver'
go

--自定義鏈接服務器的名稱並賦值當前數據庫
--鏈接服務器MyLinkedServer2的數據源是網絡名稱爲tpserver1的SQL Server
exec sp_addlinkedserver @server='mylinkedserver2',
   @srvproduct=N'',
   @provider=N'SQLOLEDB',
   @datasrc=N'tpserver1',
   @catalog=N'northwind'
go

--以四部分名稱查詢鏈接服務器MyLinkedServer1上的dbo.Orders數據表
select * from mylinkedserver1.northwind.dbo.Orders

--以四部分名稱查詢鏈接服務器MyLinkedServer1上的各個關聯數據表
select a.OrderID,a.OrderDate,b.UnitPrice,c.ProductName
from mylinkedserver1.northwind.dbo.Orders a
inner join mylinkedserver1.northwind.dbo.Order Details b
  on a.OrderID=b.OrderID
inner join mylinkedserver1.northwind.dbo.Products c
  on b.ProductID=c.ProductID
go

--將查詢命令傳送到鏈接服務器tpserver上運行
select * from openquery(tpserver,'select * from northwind.dbo.Employees')
go

/*範例3*/
/*使用Microsoft OLE DB Provider for Jet爲一個Access數據庫“北風.mdb”創建一個名稱爲“北風”的鏈接服務器*/
use master
go
exec sp_addlinkedserver
@server='北風',
@srvproduct=N'Access 2002',
@provider=N'Microsoft.Jet.OLEDB.4.0',
@datasrc=N'd:/T-SQL/Database/北風.mdb'
go

--採用SQL Server的帳戶驗證連接到SQL Server,則以用戶Admin且沒有密碼登錄鏈接服務器“北風”
exec sp_addlinkedsrvlogin '北風','false',NULL,'Admin',NULL
go
--由於Access中沒有Catalog(數據庫)與schema(所有者)名稱,因此在分佈式查詢中請使用linked_server...table_name的四部分名稱形式
select * from 北風...orders
go

/*範例4*/
/*使用Microsoft OLE DB Provider for Jet爲一個Excel工作簿“訂單.xls”創建一個名稱爲“表格”的鏈接服務器*/
提示:可以將工作簿中的每個工作表(sheet)作爲一個數據表來使用,而工作表的名稱就好比像數據表的名稱。由於Excel中沒有Catalog(數據庫)與schema(所有者)名稱,因此在分佈式查詢中請使用linked_server...table_name的四部分名稱形式。
use master
go
exec sp_addlinkedserver
@server='表格',
@srvproduct=N'Excel 2002',
@provider=N'Microsoft.Jet.OLEDB.4.0',
@datasrc=N'd:/T-SQL/Database/訂單.xls',
@location=NULL,
@provstr=N'Excel 5.0'  --提供程序字符串是'Excel 5.0'
go
--採用SQL Server的帳戶驗證連接到SQL Server,則以用戶Admin且沒有密碼登錄鏈接服務器“表格”
exec sp_addlinkedsrvlogin '表格','false',NULL,'Admin',NULL
go
--運行分佈式查詢
select * from 表格...發票
select * from 表格...產品訂貨明細

/*範例5*/
/*使用Microsoft OLE DB Provider for Jet爲d:/T-SQL/Database目錄中的所有文件創建一個名稱爲“文本服務器”的鏈接服務器*/
爲文本文件創建鏈接服務器時,請注意以下事項:
a、在sp_addlinkedserver語句中的@datasrc參數中,只需要賦值文本文件的存放路徑而不需要賦值文件名稱。事實上,所賦值路徑下的每一個文本文件都會被當作一個數據表。可以使用系統存儲過程sp_tables_ex加以查驗。
b、文本文件所在目錄必須存在一個結構描述文件schema.ini中。schema.ini用來描述各個文本文件的以便您在運行分佈式查詢時能夠正確訪問各字段的數據。事實上,當您使用Access將數據表或查詢導出到一個文本文件時,即會自動爲您創建一個shcema.ini。
c、沒有Catalog(數據庫)與schema(所有者)名稱,因此在分佈式查詢中請使用linked_server...[文本文件名稱#txt]的四部分名稱形式
use master
go
exec sp_addlinkedserver
@server='文本服務器',
@srvproduct=N'Text file',
@provider=N'Microsoft.Jet.OLEDB.4.0',
@datasrc=N'd:/T-SQL/Database',
@location=NULL,
@provstr=N'Text'  --提供程序字符串是'Text'
go
--列出鏈接服務器中的數據表,該目錄中的每個文本文件都可以被當作一個數據表來查詢
exec sp_tables_ex 文本服務器
go
--採用SQL Server的帳戶驗證連接到SQL Server,則以用戶Admin且沒有密碼登錄鏈接服務器“文本服務器”
exec sp_addlinkedsrvlogin '表格','false',NULL,'Admin',NULL
go
--運行分佈式查詢
select * from 文本服務器...[每一位客戶的訂貨總金額#txt]
select * from 文本服務器...[各年度每月訂貨小計#txt]


(三) 使用openquery()函數
openquery()函數能夠在linked_server參數所賦值名稱的鏈接服務器上運行'query'參數所賦值的查詢字符串,並將結果集返回。
openquery()函數不僅可以使用在Select命令的FROM參數中,而且根據OLE DB Provider的功能openquery()函數甚至能夠作爲
Insert、Update或Delete命令的目標數據表。雖然'query'參數所賦值的查詢字符串可能返回多個結果集,但是openquery()函數
只會返回第一個結果集。
/*範例1*/
use master
go
--鏈接服務器AccessXP的數據源是一個Access數據庫
exec sp_addlinkedserver
@server='AccessXP',
@srvproduct=N'Access 2002',
@provider=N'Microsoft.Jet.OLEDB.4.0',
@datasrc=N'D:/T-SQL/Database/北風.mdb'
go
--採用SQL Server的帳戶驗證連接到SQL Server,則以用戶Admin且沒有密碼登錄鏈接服務器AccessXP
exec sp_addlinkedsrvlogin 'AccessXP','false',NULL,'Admin',NULL
go
--鏈接服務器mylinkedserver1的數據源是網絡名稱爲tpserver1的SQL Server,並賦值當前數據庫爲northwind
exec sp_addlinkedserver
@server='mylinkedserver1',
@srvproduct=N'',
@provider=N'SQLOLEDB',
@datasrc=N'tpserver1',
@catalog=N'Northwind'
go
--鏈接服務器mylinkedserver2的數據源是網絡名稱爲tpserver2的SQL Server,並賦值當前數據庫爲northwind
exec sp_addlinkedserver
@server='mylinkedserver2',
@srvproduct=N'',
@provider=N'SQLOLEDB',
@datasrc=N'tpserver2',
@catalog=N'Northwind'
go
use northwind
go
--將openquery()函數返回從各個遠程不同種類的數據源所返回的數據加以合併然後存入一個新數據表中
select * into 新數據表
from openquery(AccessXP,'select 姓名,Datediff("yyyy",出生日期,Date()) as 年齡,地址
  from tbname where 地址 like ''%北京市%''')
union all
select * from openquery(mylinkedserver1,'select 姓名,年齡=datediff(yy,出生日期,getdate()),地址
  from tbname1 where 地址 like ''%深圳市%''')
union all
select * from openquery(mylinkedserver2,'select 姓名,年齡=datediff(yy,出生日期,getdate()),地址
  from tbname2 where 地址 like ''%天津市%''')
order by 2 desc
go
--最後來查詢我產生的新數據表
select * from 新數據表
go

--將openquery()函數返回從各個遠程不同種類的數據源所返回的數據加以鏈接以便獲得相關聯的數據
select a.客戶編號,a.公司名稱,year(b.訂單日期) as 年份,month(b.訂單日期) as 月份,
sum(c.單價*c.數量*(1-c.折扣)) as 小計
from openquery(AccessXP,'select * from 客戶') a
inner join
     openquery(mylinkedserver1,'select * from 訂單') b
on a.客戶編號=b.客戶編號
inner join
     openquery(mylinkedserver2,'select * from 訂單明細') c
on b.訂單編號=c.訂單編號
group by a.客戶編號,a.公司名稱,year(b.訂單日期),month(b.訂單日期)
order by a.公司名稱,year(b.訂單日期),month(b.訂單日期)
go


/*範例2*/
/*如果鏈接服務器的數據源是SQL Server,而且此SQL Server擁有會返回結果集的存儲過程,您可以通過OPENQUERY()函數去運行該鏈接服務器上的存儲過程*/
use master
go
--鏈接服務器mylinkedserver1的數據源是網絡名稱爲tpserver1的SQL Server,並賦值當前數據庫爲northwind
exec sp_addlinkedserver
@server='mylinkedserver1',
@srvproduct=N'',
@provider=N'SQLOLEDB',
@datasrc=N'tpserver1',
@catalog=N'Northwind'
go
--鏈接服務器mylinkedserver2的數據源是網絡名稱爲tpserver2的SQL Server,並賦值當前數據庫爲northwind
exec sp_addlinkedserver
@server='mylinkedserver2',
@srvproduct=N'',
@provider=N'SQLOLEDB',
@datasrc=N'tpserver2',
@catalog=N'Northwind'
go

--將EXEC命令傳送到鏈接服務器mylinkedserver1上運行以便運行存儲過程,由於mylinkedserver1的定義已賦值默認數據庫,
--因此在EXEC命令中不需要賦值存儲過程所屬的數據庫
select * from openquery(mylinkedserver1,'exec proc1')
--將EXEC命令傳送到鏈接服務器mylinkedserver2上運行以便運行存儲過程,由於mylinkedserver2的定義每月賦值默認數據庫,
--因此中EXEC命令中需要賦值存儲過程所屬的數據庫
select * from openquery(mylinkedserver1,'exec northwind.dbo.proc1 ''%上海市%''')
go

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