背景

Oracle PL/SQL是非常强大的一门SQL编程语言,许多Oracle用户也使用它来处理一些要求延迟低且数据一致性或可靠性要求很高的业务逻辑。

PostgreSQL也有一门非常高级的内置SQL编程语言,plpgsql。与Oracle PL/SQL语法极其类似,但是还是有一些不一样的地方。
(PS:除了plpgsql,PostgreSQL还支持C,java,python,perl等流行的语言作为数据库的函数编程语言)

本文是针对有Oracle用户遇到的一些函数语法与PostgreSQL不兼容的地方,给出的修改建议。
涉及type xx is table of xxxx index by binary_integer语法、type xx is record语法。

Oracle PL/SQL 例子

CREATE OR REPLACE FUNCTION f_xml(p_xml CLOB) RETURN INT
AS...
type rec_tk is record
(
tkno VARCHAR2(100) ,
cg_zdj number(12,0) := 0 ,
cg_jsf number(12,0) := 0
);type tklist is table of rec_tk index by binary_integer;type rec_cjr is record
(
cjrid varchar2(30) ,
tk tklist
);type cjr is table of rec_cjr index by binary_integer;
p_cjrs cjr;FOR j IN 0..v_nllen-1 LOOPBEGIN...p_cjrs(j).cjrid := v_nodevalue;...p_cjrs(j).tk(v_tkcount).tkno := v_nodevalue;p_cjrs(j).tk(v_tkcount).cg_zdj := nvl(v_nodevalue,0);p_cjrs(j).tk(v_tkcount).cg_jsf := nvl(v_nodevalue,0);...v_tkcount:=v_tkcount+1;END LOOP;

在这个例子中,用到了Oracle在PL/SQL中支持的type定义,以及type table 的定义,这个在PostgreSQL中用法不太一样。

PostgreSQL PL/SQL 兼容性例子

PostgreSQL的type定义需要在数据库中定义,而不是函数中定义。

以上PL/SQL函数在plpgsql中需要作出如下调整:
.1.

type rec_tk is record
(
tkno VARCHAR2(100) ,
cg_zdj number(12,0) := 0 ,
cg_jsf number(12,0) := 0
);type tklist is table of rec_tk index by binary_integer;

修改为
函数外执行创建类型的SQL

create type rec_tk as
(
tkno VARCHAR(100) ,
cg_zdj numeric(12,0) ,
cg_jsf numeric(12,0)
);

.2.

type rec_cjr is record
(
cjrid varchar2(30) ,
tk tklist
);type cjr is table of rec_cjr index by binary_integer;
p_cjrs cjr;

修改为
函数外执行创建类型的SQL

create type rec_cjr as
(
cjrid varchar(30) ,
tk rec_tk[]
);

函数内对table的使用修改为数组的使用,数组的下标从1开始。

p_cjrs rec_cjr[];

.3.

   p_cjrs(j).cjrid := v_nodevalue;
...p_cjrs(j).tk(v_tkcount).tkno := v_nodevalue;p_cjrs(j).tk(v_tkcount).cg_zdj := nvl(v_nodevalue,0);p_cjrs(j).tk(v_tkcount).cg_jsf := nvl(v_nodevalue,0);

plpgsql目前不能直接修改复合数组对应的composite.element
需要修改为

declarev_p_cjrs rec_cjr;v_tk rec_tk;
...v_p_cjrs.cjrid := v_nodevalue;p_cjrs[j] := v_p_cjrs.cjrid;
...v_tk.tkno := v_nodevalue;v_tk.cg_zdj := nvl(v_nodevalue,0);v_tk.cg_jsf := nvl(v_nodevalue,0);v_p_cjrs.tk[v_tkcount] := v_tk;p_cjrs[j] := v_p_cjrs;

或者请参考如下例子

do language plpgsql
$$declarevtk rec_tk;vtk_a rec_tk[];vcjr rec_cjr;vcjr_a rec_cjr[];
beginvtk := row('a', 1,2);-- or vtk.tkno := 'a'; vtk.cg_zdj := 1; vtk.cg_jsf := 2; vtk_a[1] := vtk;vcjr := row('test', vtk_a);-- or vcjr := row('test', array[row('a',1,2)]);-- or vcjr.cjrid := 'test'; vcjr.tk := vtk_a;-- or vcjr_a[1] := row('test', array[row('a',1,2)]);vcjr_a[1] := vcjr;raise notice 'vtk %, vtk_a % vcjr % vcjr_a % ', vtk, vtk_a, vcjr, vcjr_a;
end;$$
;NOTICE:  00000: vtk (a,1,2), vtk_a {"(a,1,2)"} vcjr (test,"{""(a,1,2)""}") vcjr_a {"(test,\"{\"\"(a,1,2)\"\"}\")"}
LOCATION:  exec_stmt_raise, pl_exec.c:3216
DO

nvl函数参考PostgreSQL Oracle兼容包orafce。

.4.
array用法简介
http://blog.163.com/digoal@126/blog/static/163877040201201275922529/
https://www.postgresql.org/docs/9.5/static/arrays.html
https://www.postgresql.org/docs/9.5/static/plpgsql-control-structures.html#PLPGSQL-FOREACH-ARRAY

循环

[ <<label>> ]
FOREACH target [ SLICE number ] IN ARRAY expression LOOPstatements
END LOOP [ label ];

行列转换
https://www.postgresql.org/docs/9.5/static/functions-array.html

    unnest(ARRAY[1,2])
1
2

小结

  1. 使用composite type替代了PL/SQL的type定义。
  2. 使用array替代了PL/SQL的table定义。
  3. 复合类型的数组,不能直接修改复合类型的element,需要先用标量修改好后赋值。

RDS PG内核改进建议

  1. 新增 CREATE TYPE [ IF NOT EXISTS ] 语法。这样的话用户就不需要将这个语法写在函数外了,可以在函数内直接执行。
  2. PL/SQL的type是局部变量,而PostgreSQL的type是全局的,这个也需要注意,如果多个PL/SQL函数用到了同样的type name但是结构不一样,port到plpgsql时,需要创建多个type,在plpgsql中分别使用对应的type name。
  3. plpgsql 暂时不支持composite数组直接设置element的值,需要加强plpgsql的语法功能。

PostgreSQL Oracle 兼容性 之 - PL/SQL record, table类型定义相关推荐

  1. PostgreSQL Oracle 兼容性之 - PL/SQL FORALL, BULK COLLECT

    Oracle PL/SQL 开发的童鞋,一定对O家的bulk批量处理的性能很是赞赏吧. 但是PostgreSQL用户请不要垂涎,作为学院派和工业界的一颗璀璨明珠. 开源数据库PostgreSQL,也有 ...

  2. PostgreSQL Oracle 兼容性之 - PL/SQL DETERMINISTIC 与PG函数稳定性(immutable, stable, volatile)...

    标签 PostgreSQL , Oracle , 函数稳定性 , stable , immutable , volatile , DETERMINISTIC 背景 Oracle创建pl/sql函数时, ...

  3. PostgreSQL Oracle兼容性之 - plpgsql 自治事务(autonomous_transaction)补丁

    PostgreSQL Oracle兼容性之 - plpgsql 自治事务(autonomous_transaction)补丁 作者 digoal 日期 2016-11-04 标签 PostgreSQL ...

  4. Oracle数据库之PL/SQL程序基础设计

    一.PL/SQL块结构 前边我们已经介绍了PL/SQL块的结构,再来回顾一下: DECLARE /** 声明部分--定义常量.变量.复杂数据类型.游标.用户自定义异常*/ BEGIN /** 执行部分 ...

  5. Oracle实验五 PL/SQL编程

    Oracle实验五 PL/SQL编程 [实验目的] 熟悉PL/SQL的数据类型和书写规则 熟悉控制结构和游标的使用 编写和运行函数.过程和触发器 [实验内容] 编写脚本文件,调试运行脚本文件,并记录结 ...

  6. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  7. (Oracle学习笔记) PL/SQL编程语言

    文章目录 一.PL/SQL块结构 二.注释 三.数据类型 Number(p,s) %TYPE Record %ROWTYPE 四.选择语句 If......then If....then.....el ...

  8. oracle输入数字类型吗,PL/SQL Number数字类型函数

    PL/SQL Number数字类型函数 更新时间:2007年03月21日 00:00:00   作者: ABS(x) 函数,此函数用来返回一个数的绝对值. ACOS(x)函数,返回X的反余弦值.X范围 ...

  9. Oracle Study之--PL/SQL Developer软件错误

    Oracle Study之--PL/SQL Developer软件错误 博文在51cto和CSDN同时开通 系统环境: 操作系统: Windows  XP(64) 软件:          PL/SQ ...

最新文章

  1. 欢迎加入北京智源AI社群
  2. 静态链接和动态链接优缺点
  3. 【Android 应用开发】动态权限管理示例 ( 使用原生代码实现 | 申请权限 | 判定权限申请结果 | 判定 “ 不再询问 “ 情况 )
  4. 中国互联网发展的两个瓶颈
  5. 01《软件需求分析教程》
  6. 直播 | WWW 2021:用先验知识指导BERT注意力机制的语义文本匹配
  7. Popupwin结合Timer实现定时弹出消息提示
  8. js实现html模板继承,理解JavaScript中的原型和继承
  9. matlab自考本科真题,行政管理学自考专科试题及答案
  10. 如何手动删除并重新安装 .NET Framework 2.0
  11. vue路由传参丢失问题
  12. cisco交换机端口“假死”现象
  13. 【渝粤教育】国家开放大学2018年春季 0111-22T妇产科护理学 参考试题
  14. java public就是可选吗_java 中的public
  15. ArcGIS在三调,农村土地确权,国情普查项目中常用的编辑工具
  16. pc机 串口 并口 com口 详解
  17. SDUTACM[1160]某年某月的天数
  18. ps图层模式详解带计算公式
  19. 【UE4 Cesium】加载离线地图
  20. python爬虫项目之携程网、大众点评和马蜂窝贵州景点差评实战汇总

热门文章

  1. 调试SSC1643模块透传遇到的问题
  2. 东软载波和华为鸿蒙的关系,东软载波(300183)个股分析_牛叉诊股_同花顺财经
  3. 计算机毕业设计SSM儿童成长记录与分享系统【附源码数据库】
  4. 思迅软件 数据传输服务打开提示:unable to connect sqlserver is unavailable or does not exist
  5. 【AD18】隐藏铺铜
  6. php 限制微信登陆,微信在什么情况下会被限制登录?
  7. 【CV学习笔记】图像预处理warpaffine-cuda加速
  8. 第五届双态IT乌镇用户大会-智能运维算法研讨会圆满落幕
  9. OPPOR9T_官方线刷包_救砖包_解账户锁
  10. 四大排序算法之GGBond版