达梦 dameng 数据库之升级打怪数据库兼容问题记录(1)- position 和 json 相关问题

本文讲述了公司产品如何支持国产达梦数据库,涉及position函数的使用调整和jsonb_object_agg函数在blob/clob列上的问题解决,通过实例和工作arround提供实用参考。

为了响应国家号召,为信创做出贡献,本公司的相关产品自下半年起需要逐步支持国产达梦数据库。

为此,我们将原有基于 postgresql 的相关产品进行改造,使之支持达梦数据库。这个过程,实际上就是一个升级打怪的过程,凡此种种际遇,都值得记录留存,以备后人复经此坎坷之时,加以利用。

* 关于 position 函数的用法限制与化解

此函数 postion(small_str in big_str) 是用于在 big_str 里查找是否包含 small_str 之用。在 pg 库里,两个参数都可以是表达式,没有任何的限制。但是在 dameng 这里,则必须要显示地表明两个参数为字符串类型。比如:

position( 'a' in 'abc' ) 是 ok 的

position('a' in ( select 'abc' ) )  这样就报:无法解析

但是这样又是可以的:

position('a' in ( ‘’ || select 'abc' ) )   与上一例相比,这个写法仅仅是 第二个参数使用 空串 和 后面的语句进行了连接,客观上也许可以起到告知 DB 引擎参与运算的是字符串类型。

ok,那么化解方法就是两种:

第一种:采用这种写法,即采用空串进行连接  position('a' in ( ‘’ || select 'abc' ) ) 

第二种(推荐): position('a',  (select 'abc') ) 

这第二种方案简直堪称神奇。position 尽然可以采用这种方式来调用,并且可以规避采用 in 的方式的问题。真是绝绝子了。

* 关于 jsonb_object_agg 函数导致的 “试图在blob或者clob列上排序或比较” 的解决

在一个较为复杂的查询语句里面用到了 jsonb_object_agg,这个函数的用法举例如下:

select jsonb_object_agg('key', 'value');

运行结果为:

{ "key": "value" }

也就是说可以将提供的参数拼装为 json 数据。其返回的数据类型为:TEXT。

当我在一个复杂的查询语句中使用了上述函数之后,查询出错,提示:试图在blob或者clob列上排序或比较。将 涉及 jsonb_object_agg 的语句剔除之后,就正常。由于 jsonb_object_agg 返还的是TEXT,因此我尝试在外面套一层转换,使用 cast (xxx as varchar) 将其转换为 varchar,结果仍然报错。

至此,似乎无可救药。难道就这样没辙了?在束手无策之下,只得用一个土办法,如下:

create or replace function jsonb_object_agg_varchar(key_s varchar, value_s varchar)
	return varchar
as
begin
	return '{"' || replace(key_s, '"', '\"') || '":"' || replace(value_s, '"', '\"') || '"}';
end;

也就是说,无奈之下,我们自己做了一个函数,来实现 json 数据的生成。与原生函数的差别就是其返回的数据类型为 varchar,而不是 TEXT。至此,我们将查询语句里的 函数调用改成上面的这个函数,问题就解决了。

这时,聪明的读者可能会问,那为何能不能在自制的函数里直接调用原生的函数呢?这样子岂不是逻辑上更可靠,比如:

create or replace function jsonb_object_agg_varchar(key_s varchar, value_s varchar)
	return varchar
as
begin
	return  cast(jsonb_object_agg(key_s, value_s) as varchar);
end;

其实我一开始就是这么尝试的,但是DB报了编译错误,如下:

错误号:   -4016

错误消息: 第5 行附近出现错误:
存在集函数

至此,这个 jsonb_object_agg 相关的问题就讲完了,希望对您有用。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值