SQL Server 2005 創建到 Oracle10g 的鏈接服務器

 

標記: linkserver, oracle, sqlserver, 鏈接服務器

SQL Server 2005 創建到 Oracle10g 的鏈接服務器

SQL Server 2005 異類數據源(ORACLE10G)鏈接服務器的建立

本文簡述SqlServer 2005 鏈接到 Oracle10g 服務器的過程及基本應用。

名詞說明:鏈接服務器:對應oracle的DBLINK。用於完成多個異構數據庫服務的分佈式訪問。

從 SqlServer 2005 中建立到 Oracle 的鏈接與 SQLServer 2000 中差不多,只是界面花哨了些,咋一看還以爲不一樣了呢,實際沒啥大的區別:

鏈接服務建立:
  * 安裝oracle10g 的客戶端:使用netmgr添加本地的服務命名,例如:服務命令:DBLINK;測試通過後進行下一步。
  * 建立ODBC數據源(現在已不需要,一般直接用Oracle本地服務名代替,本步可省略
   爲 SQL Server 2005 服務器增加系統數據源:
   [控制面板]=》[管理工具]=》[數據源(ODBC)]=》[系統DNS],添加基於 Oracle 的數據源:數據源名爲:DBLINK(此名稱儘量與Oracle的本地服務名一致),並進行連接測試。

  * 通過執行SQLServer存儲過程來創建鏈接服務(直接使用Oracle本地服務名,這裏本地服務名爲CMCC):
   exec sp_addlinkedserver @server='LINK2ORACLE', @srvproduct='Oracle', @provider='MSDAORA', @datasrc='CMCC'

  * 鏈接登錄配置:
   exec sp_addlinkedsrvlogin 'LINK2ORACLE',false,'sa','OracleUserName','OraclePassword' ;
   說明:此語句把遠方DBServer的scott用戶映射到本地的sa(該用戶請根據實際進行更改)。

鏈接服務器應用:
  A、查詢Oracle數據表方式一(這種方式,當Oracle與SQLServer的數據類型不一致時經常報錯,且速度稍慢):
  select * from [LINK2ORACLE]..[ORACLE_USER_NAME].TABLE_NAME;
  我在執行該語句經常報類似錯誤信息:鏈接服務器 "LINK2ORACLE" 的 OLE DB 訪問接口 "MSDAORA" 爲列提供的元數據不一致。對象 ""CMCC"."OS2_GIS_CELL"" 的列 "ISOPENED" (編譯時序號爲 20)在編譯時有 130 的 "DBTYPE",但在運行時有 5。

  B、查詢Oracle數據表方式二(經試驗,這種方式使用起來很順暢,不報錯,且速度幾乎和在Oralce中一樣快):
  select * from openquery(LINK2ORACLE,'select * from OracleUserName.TableName')
  您可以把openquery()當成表來使用。

  C、舉個例子(將Oralce用戶CMCC下的基站表OS_GIS_BASESTATION導入到SQLServer2005數據庫中):
  select * into OS_GIS_BASESTATION from openquery(LINK2ORACLE,'select * from CMCC.OS_GIS_BASESTATION')

  D、更便捷的方式:通過創建同義詞進行便捷查詢:
  CREATE SYNONYM OS_GIS_CELL FOR [ORACLELK]..[CMCC].OS_GIS_CELL;
  select * from os_gis_cell;
  select * from os_gis_cell a where a.CellName is null;

注意:涉及 Oracle 部分的 SQL 語句,尤其是 [ORACLELINK]..[ORACLE_USER_NAME].TABLE_NAME 一定要大寫,否則會報類似錯誤:
消息 7314,級別 16,狀態 1,第 1 行
鏈接服務器 "ORACLELK" 的 OLE DB 訪問接口 "MSDAORA" 不包含表 ""CMCC"."OS2_gis_CELL""。該表不存在,或者當前用戶沒有訪問該表的權限。

附:《鏈接服務器更詳細的用法說明》
USE [master]
GO
EXEC --添加服務
master.dbo.sp_addlinkedserver --命令名稱
@server = N'TEST',     --參數1,連接oracle的數據源名稱
@srvproduct=N'ORACLE',    --參數2,連接的數據源的產品名稱
@provider=N'MSDAORA',    --參數3,訪問的接口方式
@datasrc=N'ERPORA'     --參數4,被訪問的數據源名稱
GO
EXEC --添加用戶
master.dbo.sp_addlinkedsrvlogin --命令名稱
@rmtsrvname = N'TEST',    --數據源名稱
@locallogin = NULL ,    --本地登陸
@useself = N'False',    --指定用用戶名和密碼登陸
@rmtuser = N'SCOTT',     --用戶名稱
@rmtpassword = N'a123456'    --用戶密碼
go

select * from TEST..ERP.BAS_DEPT --測試結果

USE [master]
GO
EXEC --從本地 SQL Server 實例中的已知遠程服務器和鏈接服務器的列表中刪除服務器。
master.dbo.sp_dropserver
@server=N'TEST',
@droplogins='droplogins'
GO

/*語法

sp_addlinkedserver [ @server= ] 'server' [ , [ @srvproduct= ] 'product_name' ]
     [ , [ @provider= ] 'provider_name' ]
     [ , [ @datasrc= ] 'data_source' ]
     [ , [ @location= ] 'location' ]
     [ , [ @provstr= ] 'provider_string' ]
     [ , [ @catalog= ] 'catalog' ]

Oracle Microsoft OLE DB Provider for Oracle MSDAORA  用於 Oracle 數據庫的 SQL*Net 別名
Oracle,版本 8 及更高版本 Oracle Provider for OLE DB OraOLEDB.Oracle 用於 Oracle 數據庫的別名

參數
[ @server = ] 'server'
要創建的鏈接服務器的名稱。server 的數據類型爲 sysname,沒有默認值。

[ @srvproduct = ] 'product_name'
要添加爲鏈接服務器的 OLE DB 數據源的產品名稱。product_name 的數據類型爲 nvarchar(128),默認值爲 NULL。如果爲 SQL Server,則不必指定 provider_name、data_source、location、provider_string 和 catalog。

[ @provider = ] 'provider_name'
與此數據源對應的 OLE DB 訪問接口的唯一編程標識符 (PROGID)。對於當前計算機中安裝的指定 OLE DB 訪問接口,provider_name 必須唯一。provider_name 的數據類型爲 nvarchar(128),默認值爲 NULL;但如果忽略 provider_name,則使用 SQLNCLI。SQLNCLI 是 SQL 本機 OLE DB 訪問接口。OLE DB 訪問接口應以指定的 PROGID 在註冊表中註冊。

[ @datasrc = ] 'data_source'
由 OLE DB 訪問接口解釋的數據源的名稱。data_source 的數據類型爲 nvarchar(4000)。data_source 作爲 DBPROP_INIT_DATASOURCE 屬性傳遞以初始化 OLE DB 訪問接口。

[ @location = ] 'location'
由 OLE DB 訪問接口解釋的數據庫的位置。location 的數據類型爲 nvarchar(4000),默認值爲 NULL。location 作爲 DBPROP_INIT_LOCATION 屬性傳遞以初始化 OLE DB 訪問接口。

[ @provstr = ] 'provider_string'
OLE DB 訪問接口特定的連接字符串,它可標識唯一的數據源。provider_string 的數據類型爲 nvarchar(4000),默認值爲 NULL。provstr 或傳遞給 IDataInitialize 或設置爲 DBPROP_INIT_PROVIDERSTRING 屬性以初始化 OLE DB 訪問接口。

在針對 SQL 本機客戶端 OLE DB 訪問接口創建鏈接服務器後,可將 SERVER 關鍵字用作 SERVER=servername/instancename 來指定實例,以指定特定的 SQL Server 實例。servername 是運行 SQL Server 的計算機名稱,instancename 是用戶將連接到的特定 SQL Server 實例的名稱。

[ @catalog = ] 'catalog'
與 OLE DB 訪問接口建立連接時所使用的目錄。catalog 的數據類型爲 sysname,默認值爲 NULL。catalog 作爲 DBPROP_INIT_CATALOG 屬性傳遞以初始化 OLE DB 訪問接口。在針對 SQL Server 實例定義鏈接服務器時,目錄指向鏈接服務器映射到的默認數據庫。
*/

/*語法

sp_addlinkedsrvlogin [ @rmtsrvname = ] 'rmtsrvname'
     [ , [ @useself = ] 'useself' ]
     [ , [ @locallogin = ] 'locallogin' ]
     [ , [ @rmtuser = ] 'rmtuser' ]
     [ , [ @rmtpassword = ] 'rmtpassword' ]

參數
[ @rmtsrvname = ] 'rmtsrvname'
應用登錄映射的鏈接服務器的名稱。rmtsrvname 的數據類型爲 sysname,沒有默認值。

[ @useself = ] 'useself'
確定用於連接遠程服務器的登錄名。useself 的數據類型爲 varchar(8),默認值爲 TRUE。

值爲 true 時指定登錄使用自己的憑據連接 rmtsrvname,忽略 rmtuser 和 rmtpassword 參數。false 指定使用 rmtuser 和 rmtpassword 參數連接指定 locallogin 的 rmtsrvname。如果 rmtuser 和 rmtpassword 也設置爲 NULL,則不使用登錄名或密碼來連接鏈接服務器。

[ @locallogin = ] 'locallogin'
本地服務器上的登錄。locallogin 的數據類型爲 sysname,默認值爲 NULL。NULL 指定此項應用於連接到 rmtsrvname 的所有本地登錄。如果不爲 NULL,則 locallogin 可以是 SQL Server 登錄或 Windows 登錄。對於 Windows 登錄來說,必須以直接的方式或通過已被授權訪問的 Windows 組成員身份授予其訪問 SQL Server 的權限。

[ @rmtuser = ] 'rmtuser'
當 useself 爲 false 時,表示用於連接 rmtsrvname 的用戶名。rmtuser 的數據類型爲 sysname,默認值爲 NULL。

[ @rmtpassword = ] 'rmtpassword'
與 rmtuser 關聯的密碼。rmtpassword 的數據類型爲 sysname,默認值爲 NULL。
*/

/*語法
sp_dropserver [ @server = ] 'server'
     [ , [ @droplogins = ] { 'droplogins' | NULL} ]

參數
[ @server = ] 'server'
要刪除的服務器。server 的數據類型爲 sysname,無默認值。server 必須存在。

[ @droplogins = ] 'droplogins' | NULL
指示如果指定了 droplogins,那麼對於 server,還必須刪除相關的遠程服務器和鏈接服務器登錄名。@droplogins 的數據類型爲 char(10),默認值爲 NULL。
*/

/*
前提條件
1)在SQL_SERVER 2005服務器上安裝Oracle 9i的客戶端。
假設安裝到F:/oracle目錄。
注意需將ORACLE安裝後的目錄設爲Everyone權限。

(F:/oracle目錄 增加  Authenticated Users  用戶,將‘讀取和運行’權限取消掉,再勾起來,重啓windows!)
2)配置F:/oracle/product/10.2.0/client_2/network/ADMIN /tnsnames.ora 文件。

配置示例:
HAODAIFU=
(DESCRIPTION =
    (ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.8.119)(PORT = 1521)))
    (CONNECT_DATA = (SERVICE_NAME = haodaifu))
)
3)在DOS模式下運行以下命令以便確認ORACLE客戶端安裝無誤。
a:sqlplus scott/a123456@haodaifu
b:tnsping haodaifu
C:/Documents and Settings/Administrator>tnsping haodaifu
TNS Ping Utility for 32-bit Windows: Version 11.1.0.6.0 - Production on 13-12月-2007 04:36:15
Copyright (c) 1997, 2007, Oracle. All rights reserved.
已使用的參數文件:
D:/99.88.66.software/02.oracle/DB11G/11G/network/admin/sqlnet.ora
已使用 TNSNAMES 適配器來解析別名
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = 192.168.8.122)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = haodaifu))
)
OK (10 毫秒)
4)打開控制面板-服務,確認Distributed Transaction Coordinator服務已經啓動。
5)修改註冊表HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/MSDTC/MTxOCI
OracleOciLib = oci.dll
OracleSqlLib = orasql9.dll
OracleXaLib = oraclient9.dll
6)重啓SQL_SERVER服務器
7)圖形創建鏈接服務器方法--〉
A)打開SQL SERVER Management Studio,新建鏈接服務器。
B)鏈接服務器:寫上鍊接服務器的名字,如:test
C)訪問接口:選擇 Microsoft OLE DB Provider for Oracle
D)產品名稱:寫上 Oracle
E)數據源:寫上tnsnames.ora 文件中配置的服務名,如:haodaifu
F)訪問接口字符串:user id=用戶名;password=口令(可以省略)
G)選擇安全性選項頁,使用此安裝上下文建立連接:
    a.遠程登錄:scott
    b.使用密碼:tiger
H)確定
8)SQL的寫法有兩種
a)使用T-SQL語法:
 SELECT * FROM LNK1..用戶名.表名--注意用戶名稱,表名稱要大寫
b)使用PLSQL語法:
    select * from openquery(LNK1,'select * from 用戶名.表名')
    第二種訪問方式比第一種約快50%;第二種訪問方式跟直連ORACLE的速度相當;
    第一種訪問方式可能會導致一些意外錯誤,如:該表不存在,或者當前用戶沒有訪問該表的權限。
    如果需要訪問的column中使用沒有精度的數據類型,這兩種查詢方式都可能會報錯,這是ORACLE的BUG,
    無法修正,只能通過查詢語句的特殊處理規避這一問題:
    OLE DB 提供程序 'OraOLEDB.Oracle' 爲列提供的元數據不一致。執行時更改了元數據信息。

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