摘要:在当前GaussDB(DWS)的能力中主要支持两种过程化SQL语言,即基于PostgreSQL的PL/pgSQL以及基于Oracle的PL/SQL。本篇文章我们通过匿名块,函数,存储过程向大家介绍一下GaussDB(DWS)对于过程化SQL语言的基本能力。

本文分享自华为云社区《GaussDB(DWS) SQL进阶之PLSQL(一)-匿名块、函数和存储过程》,原文作者:xxxsql123 。

前言

GaussDB(DWS)中的PLSQL语言,是一种可载入的过程语言,其创建的函数可以被用在任何可以使用内建函数的地方。例如,可以创建复杂条件的计算函数并且后面用它们来定义操作符或把它们用于索引表达式。

SQL被大多数数据库用作查询语言。它是可移植的并且容易学习。但是每一个SQL语句必须由数据库服务器单独执行。

这意味着客户端应用必须发送每一个查询到数据库服务器、等待它被处理、接收并处理结果、做一些计算,然后发送更多查询给服务器。如果客户端和数据库服务器不在同一台机器上,所有这些会引起进程间通信并且将带来网络负担。

通过PLSQL语言,可以将一整块计算和一系列查询分组在数据库服务器内部,这样就有了一种过程语言的能力并且使SQL更易用,同时能节省的客户端/服务器通信开销。

  • 客户端和服务器之间的额外往返通信被消除。
  • 客户端不需要的中间结果不必被整理或者在服务器和客户端之间传送。
  • 多轮的查询解析可以被避免。

在当前GaussDB(DWS)的能力中主要支持两种过程化SQL语言,即基于PostgreSQL的PL/pgSQL以及基于Oracle的PL/SQL。本篇文章我们通过匿名块,函数,存储过程向大家介绍一下GaussDB(DWS)对于过程化SQL语言的基本能力。

匿名块的使用

匿名块(Anonymous Block)一般用于不频繁执行的脚本或不重复进行的活动。它们在一个会话中执行,并不被存储。

在GaussDB(DWS)中通过针对PostgreSQL和Oracle风格的整合,目前支持以下两种方式调用,对于Oracle迁移到GaussDB(DWS)的存储过程有了很好的兼容性支持。

√ Oracle风格-以反斜杠结尾:

语法格式:

[DECLARE [declare_statements]]
BEGIN
execution_statements
END;
/

执行用例:

postgres=# DECLARE
postgres-#      my_var VARCHAR2(30);
postgres-# BEGIN
postgres$#      my_var :='world';
postgres$#      dbms_output.put_line('hello '||my_var);
postgres$# END;
postgres$# /
hello world
ANONYMOUS BLOCK EXECUTE

√ PostgreSQL风格-以DO开头,匿名块用包起来:

语法格式:

DO [ LANGUAGE lang_name ] code;

执行用例:

postgres=# DO $$DECLARE
postgres$#      my_var char(30);
postgres$# BEGIN
postgres$#      my_var :='world';
postgres$#      raise info 'hello %' , my_var;
postgres$# END$$;
INFO:  hello world
ANONYMOUS BLOCK EXECUTE

这时细心的小伙伴们就会发现,GaussDB(DWS)不仅支持了Oracle的PL/SQL的兼容性支持,对于Oracle高级包中的dbms_output.put_line函数也做了支持。所以我们也可以将两个风格混用,发现也是支持的。(^-^)V

postgres=# DO $$DECLARE
postgres$#      my_var VARCHAR2(30);
postgres$# BEGIN
postgres$#      my_var :='world';
postgres$#      dbms_output.put_line('hello '||my_var);
postgres$# END$$;
hello world
ANONYMOUS BLOCK EXECUTE

函数的创建

既然匿名块GaussDB支持了Oracle和PostgreSQL两种风格的创建,函数当然也会支持两种啦。

下面我们一起来看看具体的使用吧!(。ì _ í。)

√ PostgreSQL风格:

语法格式:

CREATE [ OR REPLACE  ] FUNCTION function_name ( [  { argname [ argmode  ] argtype [  { DEFAULT  | :=  | =  } expression  ]}  [, ...]  ] )[ RETURNS rettype [ DETERMINISTIC  ]  | RETURNS TABLE (  { column_name column_type  }  [, ...] )]LANGUAGE lang_name [ {IMMUTABLE  | STABLE  | VOLATILE }| {SHIPPABLE | NOT SHIPPABLE}| WINDOW| [ NOT  ] LEAKPROOF  | {CALLED ON NULL INPUT  | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL  ] SECURITY INVOKER | [ EXTERNAL  ] SECURITY DEFINER | AUTHID DEFINER  | AUTHID CURRENT_USER} | {fenced | not fenced}| {PACKAGE}| COST execution_cost| ROWS result_rows| SET configuration_parameter { {TO | =} value | FROM CURRENT }}][...]{AS 'definition'| AS 'obj_file', 'link_symbol'}

执行用例:

定义函数为SQL查询的形式:

postgres=# CREATE FUNCTION func_add_sql(integer, integer) RETURNS integer
postgres-#     AS 'select $1 + $2;'
postgres-#     LANGUAGE SQL
postgres-#     IMMUTABLE
postgres-#     RETURNS NULL ON NULL INPUT;
CREATE FUNCTION
postgres=# select func_add_sql(1, 2);func_add_sql
--------------3
(1 row)

定义函数为plpgsql语言的形式:

postgres=# CREATE OR REPLACE FUNCTION func_add_sql2(a integer, b integer) RETURNS integer AS $$
postgres$#     BEGIN
postgres$#             RETURN a + b;
postgres$#     END;
postgres$# $$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# select func_add_sql2(1, 2);func_add_sql2
---------------3
(1 row)

定义返回为SETOF RECORD的函数:

postgres=# CREATE OR REPLACE FUNCTION func_add_sql3(a integer, b integer, out sum bigint, out product bigint)
postgres-# returns SETOF RECORD
postgres-# as $$
postgres$# begin
postgres$#     sum = a + b;
postgres$#     product = a * b;
postgres$#     return next;
postgres$# end;
postgres$# $$language plpgsql;
CREATE FUNCTION
postgres=# select * from  func_add_sql3(1, 2);sum | product
-----+---------3 |       2
(1 row)

√ Oracle风格:

语法格式:

CREATE [ OR REPLACE  ] FUNCTION function_name ( [  { argname [ argmode  ] argtype [  { DEFAULT | := | =  } expression  ] }  [, ...]  ] )RETURN rettype [ DETERMINISTIC  ][ {IMMUTABLE  | STABLE  | VOLATILE } | {SHIPPABLE | NOT SHIPPABLE}| {PACKAGE}| {FENCED | NOT FENCED}| [ NOT  ] LEAKPROOF  | {CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } | {[ EXTERNAL  ] SECURITY INVOKER  | [ EXTERNAL  ] SECURITY DEFINER |
AUTHID DEFINER | AUTHID CURRENT_USER
} | COST execution_cost  | ROWS result_rows  | SET configuration_parameter { {TO | =} value  | FROM CURRENT][...] { IS  | AS
} plsql_body
/

执行用例:

定义为Oracle的PL/SQL风格的函数:

实例1:

postgres=# CREATE FUNCTION func_add_sql2(a integer, b integer) RETURN integer
postgres-# AS
postgres$# BEGIN
postgres$# RETURN a + b;
postgres$# END;
postgres$# /
CREATE FUNCTION
postgres=# call func_add_sql2(1, 2);func_add_sql2
---------------3
(1 row)

实例2:

postgres=# CREATE OR REPLACE FUNCTION func_add_sql3(a integer, b integer) RETURN integer
postgres-# AS
postgres$#     sum integer;
postgres$# BEGIN
postgres$#     sum := a + b;
postgres$#     return sum;
postgres$# END;
postgres$# /
CREATE FUNCTION
postgres=# call func_add_sql3(1, 2);func_add_sql3
---------------3
(1 row)

若想使用Oracle的PL/SQL风格定义OUT参数需要使用到存储过程,请看下面章节。

存储过程的创建

存储过程与函数功能基本相似,都属于过程化SQL语言,不同的是存储过程没有返回值。

※ 需要注意的是目前GaussDB(DWS)只支持Oracle的CREATE PROCEDURE的语法支持,暂时不支持PostgreSQL的CREATE PROCEDURE语法支持。

× PostgreSQL风格:

暂不支持。

√ Oracle风格:

语法格式:

CREATE [ OR REPLACE ] PROCEDURE procedure_name[ ( {[ argmode ] [ argname ] argtype [ { DEFAULT | := | = } expression ]}[,...]) ][{ IMMUTABLE | STABLE | VOLATILE }| { SHIPPABLE | NOT SHIPPABLE }| {PACKAGE}| [ NOT ] LEAKPROOF| { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }| {[ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | AUTHID DEFINER | AUTHID CURRENT_USER}| COST execution_cost| ROWS result_rows| SET configuration_parameter { [ TO | = ] value | FROM CURRENT }][ ... ]{ IS | AS }
plsql_body
/

执行用例:

postgres=# CREATE OR REPLACE PROCEDURE prc_add
postgres-# (
postgres(#     param1    IN   INTEGER,
postgres(#     param2    IN OUT  INTEGER
postgres(# )
postgres-# AS
postgres$# BEGIN
postgres$#    param2:= param1 + param2;
postgres$#    dbms_output.put_line('result is: '||to_char(param2));
postgres$# END;
postgres$# /
CREATE PROCEDURE
postgres=# call prc_add(1, 2);
result is: 3param2
--------3
(1 row)

经过以上对GaussDB(DWS)过程化SQL语言的简单介绍,我们大致了解了在GaussDB(DWS)中匿名块,函数,存储过程的创建,下面将简单介绍一下在过程化SQL语言中的一些简单的语法介绍。

基本语法介绍

赋值:

支持 = 与 := 两种赋值符合的使用。下面两种赋值方式都是支持的。

a = b;
a := b + 1;

条件语句:

支持IF ... THEN ... END IF;   IF ... THEN  ...  ELSE ... END IF; IF ... THEN  ...  ELSEIF ... THEN ...  ELSE ... END IF;其中ELSEIF也可以写成ELSIF。

语法介绍:

-- Case 1:
IF 条件表达式 THEN--表达式为TRUE后将执行的语句
END IF;-- Case 2:
IF 条件表达式 THEN--表达式为TRUE后将执行的语句
ELSE--表达式为FALSE后将执行的语句
END IF;-- Case 3:
IF 条件表达式1 THEN--表达式1为TRUE后将执行的语句
ELSEIF 条件表达式2 THEN--表达式2为TRUE 后将执行的语句
ELSE--以上表达式都不为TRUE 后将执行的语句
END IF;

示例:

postgres=# CREATE OR REPLACE PROCEDURE pro_if_then(IN i INT)
postgres-# AS
postgres$# BEGIN
postgres$#     IF i>5 AND i<10 THEN
postgres$#         dbms_output.put_line('This is if test.');
postgres$#     ELSEIF i>10 AND i<15 THEN
postgres$#         dbms_output.put_line('This is elseif test.');
postgres$#     ELSE
postgres$#         dbms_output.put_line('This is else test.');
postgres$#     END IF;
postgres$# END;
postgres$# /
CREATE PROCEDURE
postgres=# call pro_if_then(1);
This is else test.pro_if_then
-------------(1 row)postgres=# call pro_if_then(6);
This is if test.pro_if_then
-------------(1 row)postgres=# call pro_if_then(11);
This is elseif test.pro_if_then
-------------(1 row)

循环语句:

支持while,for, foreach的使用。循环期间也可以适当添加循环控制语句continue, break。

语法介绍:

WHILE 条件表达式1 THEN--循环内需要执行的语句
END LOOP;FOR i IN result LOOP--循环内需要执行的语句
END LOOP;FOREACH var IN result LOOP--循环内需要执行的语句
END LOOP;

示例:

postgres=# CREATE OR REPLACE FUNCTION func_loop(a integer) RETURN integer
postgres-# AS
postgres$#     sum integer;
postgres$#     var integer;
postgres$# BEGIN
postgres$#     sum := a;
postgres$#     WHILE sum < 10 LOOP
postgres$#         sum := sum + 1;
postgres$#     END LOOP;
postgres$#
postgres$#     RAISE INFO 'current sum: %', sum;
postgres$#     FOR i IN 1..10 LOOP
postgres$#         sum := sum + i;
postgres$#     END LOOP;
postgres$#
postgres$#     RAISE INFO 'current sum: %', sum;
postgres$#     FOREACH var IN ARRAY ARRAY[1, 2, 3, 4] LOOP
postgres$#         sum := sum + var;
postgres$#     END LOOP;
postgres$#
postgres$#     RETURN sum;
postgres$# END;
postgres$# /
CREATE FUNCTION
postgres=# call func_loop(1);
INFO:  current sum: 10
INFO:  current sum: 65func_loop
-----------75
(1 row)

GOTO语句:

支持goto语法的使用。

语法介绍:

GOTO LABEL;--若干语句
<<label>>

示例:

postgres=# CREATE OR REPLACE FUNCTION goto_while_goto()
postgres-# RETURNS TEXT
postgres-# AS $$
postgres$# DECLARE
postgres$#     v0 INT;
postgres$#     v1 INT;
postgres$#     v2 INT;
postgres$#     test_result TEXT;
postgres$# BEGIN
postgres$#     v0 := 1;
postgres$#     v1 := 10;
postgres$#     v2 := 100;
postgres$#     test_result = '';
postgres$#     WHILE v1 < 100 LOOP
postgres$#         v1 := v1+1;
postgres$#         v2 := v2+1;
postgres$#         IF v1 > 25 THEN
postgres$#             GOTO pos1;
postgres$#         END IF;
postgres$#     END LOOP;
postgres$#
postgres$# <<pos1>>
postgres$#     /* OUTPUT RESULT */
postgres$#     test_result := 'GOTO_base=>' ||
postgres$#                    ' v0: (' || v0 || ') ' ||
postgres$#                    ' v1: (' || v1 || ') ' ||
postgres$#                    ' v2: (' || v2 || ') ';
postgres$#     RETURN test_result;
postgres$# END;
postgres$# $$
postgres-# LANGUAGE 'plpgsql';
CREATE FUNCTION
postgres=#
postgres=# SELECT goto_while_goto();goto_while_goto
-------------------------------------------GOTO_base=> v0: (1)  v1: (26)  v2: (116)
(1 row)

异常处理:

语法介绍:

[<<label>>]
[DECLAREdeclarations]
BEGINstatements
EXCEPTIONWHEN condition [OR condition ...] THENhandler_statements[WHEN condition [OR condition ...] THENhandler_statements...]
END;

示例:

postgres=# CREATE TABLE mytab(id INT,firstname VARCHAR(20),lastname VARCHAR(20)) DISTRIBUTE BY hash(id);
CREATE TABLE
postgres=# INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
INSERT 0 1
postgres=# CREATE FUNCTION fun_exp() RETURNS INT
postgres-# AS $$
postgres$# DECLARE
postgres$#     x INT :=0;
postgres$#     y INT;
postgres$# BEGIN
postgres$#     UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
postgres$#     x := x + 1;
postgres$#     y := x / 0;
postgres$# EXCEPTION
postgres$#     WHEN division_by_zero THEN
postgres$#         RAISE NOTICE 'caught division_by_zero';
postgres$#         RETURN x;
postgres$# END;$$
postgres-# LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# call fun_exp();
NOTICE:  caught division_by_zerofun_exp
---------1
(1 row)postgres=# select * from mytab;id | firstname | lastname
----+-----------+----------| Tom       | Jones
(1 row)postgres=# DROP FUNCTION fun_exp();
DROP FUNCTION
postgres=# DROP TABLE mytab;
DROP TABLE

总结:

GaussDB(DWS)对于过程化SQL语言的支持主要在PostgreSQL与Oracle上做了兼容,同时针对Oracle的一些高级包以及一些Oracle独有的语法也做了一定支持。在迁移Oracle或者PostgreSQL时,对于函数或存储过程的迁移可以减少为了兼容导致的额外工作量。

至此已经将GaussDB(DWS)中的匿名块,函数,存储过程的创建以及基本使用介绍的差不多了。当然GaussDB(DWS)对于过程化SQL语言的支持不止如此,在接下来的时间里,还将逐步向大家介绍游标,用户自定义类型等章节哟~

想了解GuassDB(DWS)更多信息,欢迎微信搜索“GaussDB DWS”关注微信公众号,和您分享最新最全的PB级数仓黑科技,后台还可获取众多学习资料哦~

点击关注,第一时间了解华为云新鲜技术~

探索GaussDB(DWS)的过程化SQL语言能力相关推荐

  1. 【梳理】数据库系统概论 第8章 数据库编程 8.1 嵌入式SQL 8.2 过程化SQL 8.3 存储过程和函数 8.4 ODBC编程

    教材:王珊 萨师煊 编著 数据库系统概论(第5版) 高等教育出版社 注:文档高清截图在后 第8章 数据库编程 标准SQL是非过程化的查询语言,操作统一.面向集合.功能丰富.使用简单.非过程化语言是相对 ...

  2. 数据库编程之过程化SQL

    SQL99标准支持过程化和函数的概念,SQL可以使用过程设计语言来定义过程和函数,也可以用关系数据库管理系统自己的过程语言来定义. 一.过程化SQL的块结构 基本的SQL是高度非过程化的语言.嵌入式S ...

  3. 十八般武艺玩转GaussDB(DWS)性能调优:总体调优策略

    摘要: 性能调优是应用迁移或开发过程中的关键步骤,同时也在整个项目实施过程中占据很大的份量,本篇主要介绍数据库级别的性能调优思路和总体策略. 性能调优是应用迁移或开发过程中的关键步骤,同时也在整个项目 ...

  4. 华为云原生数据仓库GaussDB(DWS)深度技术解读:融、快、大、稳、易

    摘要:云原生数据仓库GaussDB(DWS)架构师应邀为大家解读数仓深度技术. "云原生"在2020年成为备受瞩目的热词,云原生在确保企业数字化转型中资源快速供给.按需使用的同时, ...

  5. 一文掌握GaussDB(DWS) SQL进阶技能:全文检索

    本文分享自华为云社区<GaussDB(DWS) SQL进阶之全文检索>,原文作者:Zhang Jingyao  . 全文检索(Text search)顾名思义,就是在给定的文档中查找指定模 ...

  6. 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写

    摘要:本文将系统介绍在GaussDB(DWS)系统中影响性能的坏味道SQL及SQL模式,帮助大家能够从原理层面尽快识别这些坏味道SQL,在调优过程中及时发现问题,进行整改. 数据库的应用中,充斥着坏味 ...

  7. c是过程化语言吗数据库,关于SQL错误的是()A、所有数据库的公共语言B、非过程化的C、统一的语言D、所有用SQL缩写的程序都...

    关于SQL错误的是()A.所有数据库的公共语言B.非过程化的C.统一的语言D.所有用SQL缩写的程序都 更多相关问题 [多选] 在彩色电视机遥控系统中,属于模拟量控制的有()等几种. [多选] 在色度 ...

  8. pl/sql过程化语言

    plsql过程化语言 --控制输出-- declare begindbms_output.put_line('hello/plsql'); end; --变量的声明和使用-- declarev_num ...

  9. SQL是高级的非过程化编程语言

    结构化查询语言(Structured Query Language),简称SQL(发音:/ˈes kjuː ˈel/ "S-Q-L"),是一种特殊目的的编程语言,是一种数据库查询和 ...

最新文章

  1. 【收藏】Linux系统常用命令速查手册(附PDF下载链接)
  2. oracle数据库7个安装包,Oracle 11gR2(11.2.0.4)安装包(7个)作用说明
  3. VS2005+cygwin编译WebKit
  4. php 整数 比较,php中字符串和整数比较
  5. 小强系列之大话移动测试
  6. mysql 分组top_MySQL:如何查询出每个分组中的 top n 条记录?
  7. [css] 怎么让英文单词的首字母大写?
  8. 一年多的远程办公带给我的感悟
  9. php异常处理的好处,php异常处理方法是什么
  10. NLP算法岗面经 | 微软/腾讯/字节跳动/快手
  11. Android拍照返回图片
  12. matlab IIR滤波
  13. 分区助手扩大c盘后自动修复_分区助手怎么扩大C盘?分区助手扩大C盘的方法
  14. WordPress模板教程
  15. 分布式系统设计权衡之CAP(一致性,可用性,分区容错性)
  16. Java 添加、读取、删除PPT文档属性
  17. 从keystore(jks)文件中提取私钥
  18. 商品销售统计系统java_IMS: 基于Java实现的InventoryManagementSystem进销存管理系统
  19. linux设置mac地址命令,[转载]Linux下修改MAC地址
  20. 爬虫|巨潮资讯网上市公司年报爬取

热门文章

  1. 第十九章:李丽质入狱
  2. HTML div元素
  3. Bootstrap 警告框的外观
  4. RTP协议解析和H264码流提取
  5. 蓝昭餐饮管理系统服务器无法连接,服务器安全加固操作指南.docx
  6. 电竞高性能主机可以改云服务器吗,无缘主机平台 NBA 2K League电竞联赛将改用高性能PC...
  7. 码风改变计划(暂定)
  8. Springboot配置fastjson开发
  9. unicorn模拟执行学习
  10. [转]ubuntu network is unreachable 解决记