Postgresql ODBC驅動,用sqlserver添加dblink跨庫訪問postgresql數據庫

在一樣是SQLserver數據庫跨庫訪問時,只須要如下方法sql

declare @rowcount int
set @rowcount = 0
set @rowcount =(select COUNT(*) from sys.servers where name = 'ITSV2')
if @rowcount <= 0 
begin
exec sp_addlinkedserver  'ITSV2', ' ', 'SQLOLEDB', '192.168.0.222,8989'   --IP,端口號
end 
exec sp_addlinkedsrvlogin 'ITSV2','false',null, 'sa', 'sa1234' --數據庫連接帳號、密碼
--select * from [ITSV2].數據庫.dbo.表 

 

作項目的時候遇到數據對接問題,須要從其餘地方同步數據到本項目,本項目是使用sqlserver數據庫,而對方使用的是postgresql數據庫。數據庫

1、下載安裝postgresql ODBC驅動

在PostgreSql官網下載ODBC驅動,網址:https://www.postgresql.org/ftp/odbc/versions/msi/服務器

本數據庫所在的服務器是64位,我找最新版本的64位的ide

 

 

下載下來爲  psqlodbc_x64.msi工具

 

在網上有人下載使用的的另外一個,這個是收費的,可是有無償使用期。sqlserver

 

下載好後放在本項目數據庫所在服務器上,安裝,直接點下一步就行了,post

2、ODBC添加數據源

找到控制面板--管理工具--數據源(ODBC)--系統DSN測試

找到postgresql-完成 ,而後輸入對方的數據庫信息,點擊測試,顯示鏈接成功。說明和對方的數據庫能夠鏈接了。spa

 

 

3、數據庫添加dblink,鏈接對方postgresql,查詢數據

一、在數據庫中添加linkedserverpostgresql

execute sp_addlinkedserver 
    @server='sourceDB',    --被訪問的服務器別名,能夠本身定義
        @srvproduct='Any',
        @provider='MSDASQL',
        @datasrc='PostgreSQL35W'    --被訪問的服務器地址(IP地址,端口號\服務器名稱)  --PostgreSQL35W 上面第二步設置的名稱 --建立本地用戶與遠程服務器中用戶之間的映射

execute sp_addlinkedsrvlogin 
    @rmtsrvname='sourceDB',    --被訪問的服務器別名 ,
        @useself='false',    --是否經過模擬本地登陸名或顯式提交登陸名和密碼來鏈接到遠程服務器
        @locallogin=null,    --本地登陸
        @rmtuser='user01',    --對方數據庫用戶名
        @rmtpassword='123456'    --對方數據庫密碼

 二、select * from sys.servers 查到剛纔添加的,說明添加成功。

--顯示的linkedserver
--select * from sys.servers

--同步數據後 能夠關閉鏈接,
--刪除運行本地與遠程之間的用戶映射 --execute sys.sp_droplinkedsrvlogin @rmtsrvname='sourceDB',@locallogin=null --刪除連接服務器 --execute sys.sp_dropserver @server='sourceDB'

 三、查詢數據

此處可能會遇到的問題:

(1)對方postgresql版本可能較低,須要查詢語句中字段、表名都須要加雙引號,若是不加會出錯,提示不存在表

錯誤信息:

連接服務器"sourceDB"的 OLE DB 訪問接口 "MSDASQL" 返回了消息 "ERROR: relation "lgs_purchaseorder" does not exist;
No query has been executed with that handle"。
消息 7350,級別 16,狀態 2,第 114 行
沒法從連接服務器 "sourceDB" 的 OLE DB 訪問接口"MSDASQL"獲取列信息。

(2)報如下錯誤,通常在查找數字列的時候出現,這個是所查出的數字精度比較大,而sqlserver 查出所表示的精度沒有那麼大

解決方法能夠是不查數字列,或者是將該數字列轉換成字符串表達

SELECT * from openquery(sourceDB,'select "OrderNo","ItemNo","PartNo","Qty" from "LGS_PurchaseOrder" order by "OrderNo" desc limit 100') --查詢報如下錯誤

消息 7356,級別 16,狀態 1,第 112 行
連接服務器 "sourceDB" 的 OLE DB 訪問接口 "MSDASQL" 爲列提供的元數據不一致。
對象 "select "OrderNo","ItemNo","PartNo","Qty" from "LGS_PurchaseOrder" order by "OrderNo" desc limit 100"
的列 "Qty" (編譯時序號爲 4)在編譯時有 6 的 "SCALE",但在運行時有 8。

 調整:將數字列調整爲字符串

SELECT * from openquery(sourceDB,'select "OrderNo","ItemNo","PartNo",cast("Qty" as char(30)) from "LGS_PurchaseOrder" order by "OrderNo" desc limit 100')

結果:調整後就能夠查出數據,就能夠拿對方數據庫得數據作本身的業務邏輯操做了。

(3) 如何在存儲過程當中用openquery加參數化查詢

通常的加寫死的參數方法爲

SELECT * from openquery(sourceDB,
'select "OrderNo","ItemNo","PartNo","WindowTime","CloseTime" from "LGS_PurchaseOrder" where "WindowTime" > ''2019-12-18 16:00:00.0000000'' '); 

若是須要把條件換成參數,下面這樣是不行的,會提示語法錯誤,

--DECLARE @nowdate NVARCHAR(50)
--SET @nowdate = '2018-08-18 16:00:09.0000000'
SELECT * from openquery(sourceDB,
'select "OrderNo","ItemNo","PartNo","WindowTime","CloseTime" from "LGS_PurchaseOrder" 
where "WindowTime" > '''+@nowdate+'''   limit 100')

正確的解決方法是用exec執行方式,以下

DECLARE @b VARCHAR(50)
DECLARE @sql varchar(500)
DECLARE @nowdate NVARCHAR(50)
SET @nowdate = '2019-12-18 16:00:09.0000000'
SET @sql ='select * from openquery (sourceDB,''select "OrderNo","ItemNo","PartNo","WindowTime","CloseTime"
 from "LGS_PurchaseOrder" where "WindowTime"> '''''+@nowdate+''''''')';
EXEC(@sql)
相關文章
相關標籤/搜索