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)
相关文章
相关标签/搜索