使用dblink首先要去调用和被调用两个服务的库里执行dblink的创建语句
create extension if not exists dblink;
目前只测试了dblink的方式,business服务和user服务之间有跨库的连表操作,但是一般直接指定库名.模式.表明去连表,肯定会报错
com.kingbase8.util.KSQLException: 错误: 未实现跨数据库关联: "user.public.sys_org"
原sql:
select
count(*)
from
tbl_business
where
deleted=0
and
EXISTS(
SELECT
id
FROM
user.public.sys_org
WHERE
org_id = id
and
(id = #{orgId} or parent_ids LIKE concat( '%',(#{orgId}),',%' ))
);
这里的意思就是要查询business表中的orgid是否在org表的id或者父id中存在(父id是用,号拼接所以用like去匹配),如果存在就查出来
我这边利用系统中的系统参数,把dblink的sql去存入,在执行sql前,把sql当做传参传入sql中.
host:地址
port:端口
dbname:库名
user:账号
password:密码
SELECT s.id, s.parent_ids FROM dblink ( 'host=localhost port =54321 dbname=user user=system password=system123', 'SELECT id,parent_ids FROM user.public.sys_org' )AS s ( id VARCHAR ( 200 ), parent_ids VARCHAR ( 200 ) ) WHERE org_id = s.id AND ( s.id = 'orgId' OR s.parent_ids LIKE '%'||'orgId'||',%' )
这条sql拼到EXISTS中
select
count(*)
from
tbl_business
where
deleted=0
and
EXISTS(
SELECT s.id, s.parent_ids FROM dblink ( 'host=localhost port =54321 dbname=user user=system password=system123', 'SELECT id,parent_ids FROM user.public.sys_org' )AS s ( id VARCHAR ( 200 ), parent_ids VARCHAR ( 200 ) ) WHERE org_id = s.id AND ( s.id = 'orgId' OR s.parent_ids LIKE '%'||'orgId'||',%' )
);
注意这里like不能使用concat,kingbase会在预编译时报错,如下:
com.kingbase8.util.KSQLException: 错误: 语法错误 在 "$xxx" 或附近的
原因分析:
对于mysql 的 like 而言,一般都要用 like concat() 组合,可以防止sql注入。
人大金仓的kingbase底层还是pgsql的内核,使用pgsql时添加了参数stringtype=unspecified,就会报无法确定参数类型的错。
解决方法:
第一种(无法防止sql注入,不是最佳解决办法):
like '%${params.xxx}%'
第二种(最佳方案):
name like '%'||#{params.name}||'%'
第三种(使用TEXT强制转换数据类型为字符串):
name like CONCAT('%', #{params.name}::text, '%')