KingbaseES 为了更好地适应用户的oracle 应用,实现了对 plsql 的支持,用户可以根据需要使用 plsql 或 plpgsql。 以下简要介绍下二者的差异

一、格式差异

1、plpgsql

plpgsql 必须有 label

[ <<label>> ]
[ DECLARE declarations ]
BEGIN
statements
END [ label ];

具体例子:

create or replace function pgsql_test(part integer)
returns integer as $$
declare
v_total integer;
begin
if part = 0 then
select count(*) into v_total from t0;
else
select count(*) into v_total from t1;
end if;
return v_total;
end;
$$ language plpgsql;

2、plsql

plsql 不需要有 label

create or replace function plsql_func01(part integer)
returns integer as
declare
v_total integer;
begin
if part = 0 then
select count(*) into v_total from t0;
else
select count(*) into v_total from t1;
end if;
return v_total;
end;

如果后面没有指明language,KingbaseES 视database_mode参数决定采用哪种解析器。如果database_mode=oracle,默认采用的是plsql 解析器;如果database_mode=pg,则默认采用plpgsql解析器。

二、plsql 支持存储过程

PG11之前,对于plpgsql,函数实际上也称作存储过程,也就是实际没有 create procedure 的概念,函数可以完成数据库的DML操作,实际 function 和 procedure 功能上没有区别。

KingbaseES plsql 同时支持 function and procedure,与oracle function不同,KingbaseES function内部可以进行DML操作。

procedure:过程调用 call plsql_proc01();

create or replace procedure plsql_proc01
as
begin
insert into t0 values(1);
end;

function:函数调用 select plsql_func01();

create or replace function plsql_func01
return integer as
begin
insert into t0 values(1);
return 1;
end;

注:oracle plsql,function 必须作为表达式一部分进行调用,函数体内如果有 DML操作,在调用时是会报错,函数含有自治事务的除外。

三、是否支持嵌套事务

1、plpgsql

plpgsql 并不支持嵌套事务,函数中的事务总是由外层命令(函数的调用者)来控制的,它们本身无法开始或提交事务。

pgisdb=> create or replace function plsql_test(part integer)
pgisdb-> returns integer as
pgisdb-> declare
pgisdb-> v_total integer;
pgisdb-> begin
pgisdb-> if part = 0 then
pgisdb-> select count(*) into v_total from t0;
pgisdb-> commit;
pgisdb-> else
pgisdb-> select count(*) into v_total from t1;
pgisdb-> end if;
pgisdb-> return v_total;
pgisdb-> end;
pgisdb-> /
CREATE FUNCTION

pgisdb=> select plsql_test(0);
ERROR: invalid transaction termination
CONTEXT: PL/SQL function plsql_test(integer) line 7 at COMMIT

2、plsql

对于function,不支持函数体内 commit ,事务是否提交由外层事务决定。在V8R6C5版本,将支持函数commit。

pgisdb=> create or replace function plsql_func01
pgisdb-> return integer as
pgisdb-> begin
pgisdb-> insert into t0 values(1);
pgisdb-> commit;
pgisdb-> return 1;
pgisdb-> end;
pgisdb-> /
CREATE FUNCTION

pgisdb=> select plsql_func01();
ERROR: invalid transaction termination
CONTEXT: PL/SQL function plsql_func01() line 4 at COMMIT

对于procedure,内部允许commit or rollback。

pgisdb=> create or replace procedure plsql_proc01
pgisdb-> as
pgisdb-> begin
pgisdb-> insert into t0 values(1);
pgisdb-> commit;
pgisdb-> end;
pgisdb-> /
CREATE PROCEDURE pgisdb=> call plsql_proc01();
CALL

注意:如果过程体内含有commit or rollback,则不能在外层再 begin transaction。

pgisdb=> create or replace procedure plsql_proc01
pgisdb-> as
pgisdb-> begin
pgisdb-> insert into t0 values(1);
pgisdb-> commit;
pgisdb-> end;
pgisdb-> /
CREATE PROCEDURE pgisdb=> begin;
BEGIN
pgisdb=> call plsql_proc01();
ERROR: invalid transaction termination
CONTEXT: PL/SQL function plsql_proc01() line 4 at COMMIT

四、性能比较

create or replace function pgsql_test()
returns integer as $$
declare
v_total integer;
begin
select count(*) into v_total from t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
return v_total;
end;
$$ language plpgsql; test=# begin
test-# for i in 1..100000 loop
test-# perform pgsql_test();
test-# end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 2450.671 ms (00:02.451) ============ create or replace function plsql_test()
returns integer as
declare
v_total integer;
begin
select count(*) into v_total from t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
return v_total;
end;
/ test=# begin
test-# for i in 1..100000 loop
test-# perform plsql_test();
test-# end loop;
test-# end;
test-# /
ANONYMOUS BLOCK
Time: 2454.302 ms (00:02.454)

五、其他差异

1、循环变量定义

plsql: 循环变量 i 可以不用提前定义

create or replace procedure plsql_proc() as
begin
for i in select regexp_split_to_table('ab,bc,cd',',') loop
raise notice '%',i;
end loop;
end;

plpgsql: 循环变量必须提取定义

create or replace procedure plpgsql_proc() as
$$
begin
for i in select regexp_split_to_table('ab,bc,cd',',') loop
raise notice '%',i;
end loop;
end;
$$ language plpgsql; ERROR: loop variable of loop over rows must be a record variable or list of scalar variables
LINE 4: for i in select regexp_split_to_table('ab,bc,cd',',') loop create or replace procedure plpgsql_proc() as
$$
declare
v_text text;
begin
for v_text in select regexp_split_to_table('ab,bc,cd',',') loop
raise notice '%',v_text;
end loop;
end;
$$ language plpgsql;

2、execute & execute immediate

plsql 支持 execute or execute immediate , plpgsql 只支持 execute

PLSQL 与 PLPGSQL的更多相关文章

  1. plpgsql insert 性能 测试

    有时需要执行一些sql脚本,带逻辑控制语句,又不想用高级语言C#.Java之类的,可以直接用plpgsql,类似于Oracle的plsql. do language 'plpgsql' $$ decl ...

  2. plpgsql 编译执行

    Oracle 的存储过程或函数提供了两种执行方式: 解释执行:将源代码逐条转换成目标代码,解释一条,执行一条的过程.PLPGSQL将语句翻译成中间形式的系统代码,并在运行时进行解释. 编译执行:将源代 ...

  3. PLSql Oracle配置

    1.安装Oracle客户端或者服务端 2.配置环境变量 <1>.一般如果安装了Oracle客户端或者服务端的话,在环境变种的Path中有Oracle的安装路径(计算机-属性-高级系统设置- ...

  4. plsql查询乱码问题解决

    步骤一:新建变量,设置变量名:NLS_LANG,变量值:SIMPLIFIED CHINESE_CHINA.ZHS16GBK,确定即可: 步骤二: 退出plsql,重新登陆plsql.输入sql语句,执 ...

  5. Oracle/PLSQL: ORA-06550

    参考: http://blog.csdn.net/haiross/article/details/20612135 Oracle/PLSQL: ORA-06550 Learn the cause an ...

  6. [No00008F]PLSQL自动登录,记住用户名密码&日常使用技巧

    配置启动时的登录用户名和密码 这是个有争议的功能,因为记住密码会给带来数据安全的问题. 但假如是开发用的库,密码甚至可以和用户名相同,每次输入密码实在没什么意义,可以考虑让PLSQL Develope ...

  7. 使用plsql创建表空间和用户

    使用plsql创建oracle数据库的表空间和用户,并授权的语句.1.创建表空间:说明:datafile是指定创建位置,指向oracle数据库的默认位置:autoextend 设置容量为自动增长,50 ...

  8. plsql查找不到带中文的纪录

    今天在另外的电脑用plsql查询不到带中文的记录 select * from test where name like '%测试%' 然后发现是系统的环境变量还没设置好所造成的.在系统变量加入如下变量 ...

  9. plsql配置远程连接数据库

    1.先安装plsql.地址:http://pan.baidu.com/s/1hqGbATI 2.  解压缩 instantclient_11_2(这个客户端可以在网上找精简版的),找到以下路径  \i ...

随机推荐

  1. RPA-UiPath视频教程2

    UiPath参数的介绍和使用 https://www.bilibili.com/video/av83343849 UiPath第一个案例HelloWorld https://www.bilibili. ...

  2. 由ASP.NET Core根据路径下载文件异常引发的探究

    前言 最近在开发新的项目,使用的是ASP.NET Core6.0版本的框架.由于项目中存在文件下载功能,没有使用类似MinIO或OSS之类的分布式文件系统,而是下载本地文件,也就是根据本地文件路径进行 ...

  3. Java创建TXT文件并写入 内容

    public static void main(String[] args) { String filePath = "E:/" + "1.txt"; Stri ...

  4. 浏览器js调试

    经常忘记,还是需要记录一下啊 右键,检查元素 在元素DOM节点右击,复制CSS选择器 function sleep (time) { return new Promise((resolve) => ...

  5. python+tkinter 简单的登录窗口demo

    一个简单的登录窗口布局,可以用于日常快速搭建一个简单的窗口类. from tkinter import * import tkinter.messagebox class LoginUi: def _ ...

  6. ajax01_基础知识

    ajax请求 ajax概述 组成:asynchronous + javascript + xml 特点: 可发送异步请求(这也是与传统请求方式的区别) 用javascript语言编写代码 前后端数据交 ...

  7. flush方法和close方法的区别和字符输出流写数据的其他方法和字符输出流的续写和换行

    flush方法和close方法的区别 flush:刷新缓冲区,流对象可以继续使用 close:先刷新缓冲区,然后通知系统释放资源.刘对象不可以再被使用了. public class demo02 { ...

  8. python 常用的魔法函数

    简介 在实际项目中,我们其实并不会太多的使用魔法函数,但是一些方法或者函数均是有魔法函数演变而来的,且在一些面试过程中会遇到一些关于常见方法的实现,就会牵扯到相应的魔法函数,此处将介绍一些我认为比较常 ...

  9. Changes in GreatSQL 8.0.25-16(2022-5-16)

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 目录 1.新增特性 1.1 新增仲裁节点(投票节点)角色 1.2 新增快速单主模式 1.3 新增MGR网络开销阈值 1.4 ...

  10. 使用 Liquibase 管理数据库版本 - SpringBoot 2.7 .2 实战基础

    优雅哥 SpringBoot 2.7 .2 实战基础 - 05 -使用 Liquibase 管理数据库版本 在企业开发中,数据库版本管理好像是一个伪命题,大多项目都是通过 Power Designer ...