PostgreSQL能否不使用括号调用函数/存储过程以兼容Oracle调用风格?
问题背景
当前正在进行Oracle到PostgreSQL 11.11的数据库迁移,遇到遗留Java代码调用无参存储函数的语法适配问题:
- Oracle侧原逻辑支持无括号调用无参函数,原调用格式为
ad.ctlpk.proc,对应函数定义为FUNCTION Proc RETURN INT - 迁移到PostgreSQL后,函数已改写为
CREATE FUNCTION ad_ctlpk.proc() RETURNS INTEGER,但PostgreSQL要求无参函数调用必须加(),直接修改调用配置为ad_ctlpk.proc()后触发SQL语法报错syntax error at or near "(" - 迁移初期限制仅可修改数据库侧对象,无法调整Java代码及相关组件
数据库侧适配方案(仅适用于临时兼容场景)
PostgreSQL中仅内置的特殊时间函数(如current_timestamp对应now())支持无括号调用语法,自定义函数默认无法直接实现无括号调用,仅可通过以下间接方案尝试兼容,局限性较高:
- 创建同名自定义配置参数,通过参数钩子函数触发原函数逻辑
-- 首先添加自定义参数 SET custom_variable_classes = 'ad_ctlpk'; ALTER DATABASE 你的数据库名 SET ad_ctlpk.proc = 0; -- 后续创建事件触发器或者使用参数钩子,在读取该参数时自动调用proc()函数返回对应值 -- 注意:该方案实现复杂,且仅适用于函数返回值固定、无副作用的场景,无法支持带写入逻辑的函数调用 - 改用视图模拟
如果你的函数无参数、无副作用且返回单值,可以创建同名视图替代函数:CREATE VIEW ad_ctlpk.proc AS SELECT ad_ctlpk.proc() AS return_val; -- 此时调用SELECT * FROM ad_ctlpk.proc可获取返回值,但仅适配SELECT调用场景,无法适配存储过程调用语法
最终可行方案
上述数据库侧兼容方案都存在强场景限制,无法适配通用的存储过程/函数调用场景。PostgreSQL官方不支持自定义无括号无参函数的调用语法,因此最优解是修改Java代码侧的调用逻辑,在无参函数调用处补充()即可解决语法报错问题。
由于PostgreSQL不支持无括号创建或调用自定义函数,最终已申请修改Java代码,在需要的函数调用处添加
(),问题已解决。
内容的提问来源于stack exchange,提问作者aashoo
相关产品推荐
相关产品推荐

