PLSQL 与 PLPGSQL
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的更多相关文章
- plpgsql insert 性能 测试
有时需要执行一些sql脚本,带逻辑控制语句,又不想用高级语言C#.Java之类的,可以直接用plpgsql,类似于Oracle的plsql. do language 'plpgsql' $$ decl ...
- plpgsql 编译执行
Oracle 的存储过程或函数提供了两种执行方式: 解释执行:将源代码逐条转换成目标代码,解释一条,执行一条的过程.PLPGSQL将语句翻译成中间形式的系统代码,并在运行时进行解释. 编译执行:将源代 ...
- PLSql Oracle配置
1.安装Oracle客户端或者服务端 2.配置环境变量 <1>.一般如果安装了Oracle客户端或者服务端的话,在环境变种的Path中有Oracle的安装路径(计算机-属性-高级系统设置- ...
- plsql查询乱码问题解决
步骤一:新建变量,设置变量名:NLS_LANG,变量值:SIMPLIFIED CHINESE_CHINA.ZHS16GBK,确定即可: 步骤二: 退出plsql,重新登陆plsql.输入sql语句,执 ...
- Oracle/PLSQL: ORA-06550
参考: http://blog.csdn.net/haiross/article/details/20612135 Oracle/PLSQL: ORA-06550 Learn the cause an ...
- [No00008F]PLSQL自动登录,记住用户名密码&日常使用技巧
配置启动时的登录用户名和密码 这是个有争议的功能,因为记住密码会给带来数据安全的问题. 但假如是开发用的库,密码甚至可以和用户名相同,每次输入密码实在没什么意义,可以考虑让PLSQL Develope ...
- 使用plsql创建表空间和用户
使用plsql创建oracle数据库的表空间和用户,并授权的语句.1.创建表空间:说明:datafile是指定创建位置,指向oracle数据库的默认位置:autoextend 设置容量为自动增长,50 ...
- plsql查找不到带中文的纪录
今天在另外的电脑用plsql查询不到带中文的记录 select * from test where name like '%测试%' 然后发现是系统的环境变量还没设置好所造成的.在系统变量加入如下变量 ...
- plsql配置远程连接数据库
1.先安装plsql.地址:http://pan.baidu.com/s/1hqGbATI 2. 解压缩 instantclient_11_2(这个客户端可以在网上找精简版的),找到以下路径 \i ...
随机推荐
- 【Nginx】Windows平台下配置Nginx服务实现负载均衡
前言:废话不多说了,直接上步骤. 系统环境:win10 测试用的开发环境和服务类型:VS2022 + DotNet 6 + WebApi 1.本地先创建一个webapi项目,用于测试使用. 2.新建一 ...
- 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 数据结构-二叉树(Binary Tree)
1.二叉树(Binary Tree) 是n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根节点和两棵互不相交的,分别称为根节点的左子树和右子树的二叉树组成. 2.特数二 ...
- day06 Socket_线程API_线程并发安全
使用多线程实现多客户端连接服务端 流程图 服务端代码改造: package socket; import java.io.BufferedReader; import java.io.IOExcept ...
- HTML js 复习
<a href="#top" target="_self">返回顶部</a> 返回页面顶部代码 打印js对象方法 function wr ...
- 【点击云游台湾省】今天,老子云在台湾省建了个3D房子!
今日热搜仍然聚焦台湾省,中国新闻网发文:地图已经可以显示台湾省的每个街道.网友一片叫好! 台湾省通过平面图观察,难免看的不够真切,其实现在已经可以通过3D视角云游台湾省了! 老子云这次通过自研技术,还 ...
- 先导,对IOC容器的理解
先导,对IOC容器的理解 通俗的讲就是把你的class类交给spring的IOC容器去管理 需要对该类的属性注入一些值,就可以通过spring提供的xml文件或者注解进行注入 自己使用时在IOC容器工 ...
- 蔚来杯2022牛客暑期多校训练营7 CFGJ
比赛链接 C 题解 方法一 知识点:思维. 先统计没有出现的数,每个都可以随便放,所以作为补位用的. 将原数组左移一位作为预定的答案数组,然后开始检查.如果和原数组一样,则用补位数字填充,如果不一样就 ...
- mybatis 04: mybatis对象分析 + 测试代码简化 + 配置优化
MyBatis对象分析 测试代码示例 package com.example.test; import com.example.pojo.Student; import org.apache.ibat ...
- OC高仿iOS网易云音乐AFNetworking+SDWebImage+MJRefresh+MVC+MVVM
效果 因为OC版本大部分截图和Swift版本一样,所以就不再另外截图了. 列文章目录 因为目录比较多,每次更新这里比较麻烦,所以推荐点击到主页,然后查看iOS云音乐专栏. 目简介 这是一个使用OC语言 ...