为了响应国家号召,为信创做出贡献,本公司的相关产品自下半年起需要逐步支持国产达梦数据库。
为此,我们将原有基于 postgresql 的相关产品进行改造,使之支持达梦数据库。这个过程,实际上就是一个升级打怪的过程,凡此种种际遇,都值得记录留存,以备后人复经此坎坷之时,加以利用。
此函数 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,这个函数的用法举例如下:
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 相关的问题就讲完了,希望对您有用。