浅谈DWS函数出参方式
函数 方式 浅谈 DWS
2023-09-27 14:19:58 时间
摘要:DWS的PL/pgSQL函数/存储过程中有一个特殊的语法PERFORM语法,用于执行语句但是丢弃执行结果的场景,常用于一些状态判断的场景。
本文分享自华为云社区《GassDB(DWS)功能 -- 函数出参 #【玩转PB级数仓GaussDB(DWS)】》,作者:譡里个檔。
DWS的PL/pgSQL函数/存储过程中有一个特殊的语法PERFORM语法,用于执行语句但是丢弃执行结果的场景,常用于一些状态判断的场景。但是客户往往会不当使用PERFORM语法,导致业务逻辑出错,最常见的就是使用PERFORM执行带有出参的函数。
已知函数inner定义如下
CREATE OR REPLACE FUNCTION public.inner( IN a1 integer, IN b1 integer, OUT a integer, OUT b integer ) RETURNS record LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE BEGIN a := a1; b := b1; END$function$ ;
函数f_outer定义如下,函数体中调用函数inner,把函数的出参赋值给变量a, b
CREATE OR REPLACE FUNCTION public.f_outer(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int; b int; BEGIN PERFORM public.inner(i_a, i_b, a, b); RAISE INFO 'a = %, b = %', a, b; END$function$ ;
但是实际执行的时候发现函数inner的出参没有正确赋值(预期值为a = 1 b = 11)。
postgres=# CALL f_outer(1, 11); INFO: a = <NULL>, b = <NULL> SQLSTATE: 00000 f_outer --------- (1 row) Time: 1.086 ms
出现这种问题的原因是PERFORM语法会执行SQL语句,但是会抛弃执行结果,导致函数出参没有赋值
DWS中常用的带出函数出参的方式有以下三种:
- 方式1:函数出参的方式赋值
CREATE OR REPLACE FUNCTION public.test1(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int; b int; BEGIN public.inner(i_a, i_b, a, b); RAISE info 'a = %, b = %', a, b; END$function$ ;
- 方式2:动态查询语句方式赋值
CREATE OR REPLACE FUNCTION public.test2(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int; b int; BEGIN EXECUTE IMMEDIATE 'SELECT * from public.inner(:1, :2)' UNSING INTO a, b USING IN i_a, i_b; RAISE INFO 'a = %, b = %', a, b; END$function$ ;
- 方式3:SELECT .. INTO赋值
CREATE OR REPLACE FUNCTION public.test3(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int := 0; b int := 0; BEGIN SELECT * INTO a, b FROM public.inner(i_a, i_b); RAISE INFO 'a = %, b = %', a, b; END$function$ ;
相关文章
- 学会这5种JS函数继承方式,前端面试你至少成功50%
- 深度学习-Pytorch:构建DNN神经网络模型【构建方式:自定义函数及参数、nn.Module()、nn.Module()&nn.Sequential()】、Visdom可视化
- LayoutInflater的inflate函数用法详解
- 面向过程,面向对象,函数式对同一个问题的思考方式
- Python zip()函数实现并行迭代
- python函数 传参的多种方式 解读
- 【Python】元组的创建方式:使用()或者 使用内置函数 tuple()
- 关于类成员函数中访问同类对象的私有成员
- 第11.22节 Python 中re模块的字符串分割器:split函数
- 通俗易懂方式解说Python中repr(变量)和str(变量)函数的区别
- 默认实参等价于定义了一系列重载函数
- 初等数论初步——剩余类和欧拉函数
- 第19章 SVC中断方式调用用户函数
- 23.C++- 继承的多种方式、显示调用父类构造函数、父子之间的同名函数、virtual虚函数
- ELF文件的加载过程(load_elf_binary函数详解)--Linux进程的管理与调度(十三)