浅谈DWS函数出参方式

浅谈,dws,函数,方式 · 浏览次数 : 29

小编点评

## Summary This document discusses the issue with the `PERFORM` syntax in DWS PL/pgSQL functions and stored procedures. The main purpose of `PERFORM` is to execute a statement without storing its result, which can be useful for certain state-checking scenarios. However, due to the way `PERFORM` is used, it often leads to incorrect variable assignments. Here's a breakdown of the issue: * `inner` function call passes its arguments to variables `a` and `b`. * `a` and `b` are subsequently assigned the values of `i_a` and `i_b`, respectively. * `a` and `b` are used in the `RAISE INFO` statement without being properly assigned. This leads to misleading results, as the actual values of `a` and `b` are not captured and used. **Possible solutions:** * Use alternative methods for passing arguments, such as `IN` or dynamic queries. * Use `INTO` assignment with `SELECT` to capture the result of the inner function. **Example:** ```sql -- Method 1: Using IN CREATE OR REPLACE FUNCTION public.test1(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLEAS $function$ DECLARE a int; b int;BEGIN public.inner(i_a, i_b, a, b); RAISE info 'a = %, b = %', a, b;END$function; -- Method 2: Using Dynamic Query CREATE OR REPLACE FUNCTION public.test2(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLEAS $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; ``` **Conclusion:** Understanding the `PERFORM` syntax and its limitations is crucial for working with DWS PL/pgSQL functions and stored procedures. By implementing the suggested solutions, you can achieve accurate variable assignments and improve your code's clarity and efficiency.

正文

摘要: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$
;

 

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

与浅谈DWS函数出参方式相似的内容:

浅谈DWS函数出参方式

摘要:DWS的PL/pgSQL函数/存储过程中有一个特殊的语法PERFORM语法,用于执行语句但是丢弃执行结果的场景,常用于一些状态判断的场景。 本文分享自华为云社区《GassDB(DWS)功能 -- 函数出参 #【玩转PB级数仓GaussDB(DWS)】》,作者:譡里个檔。 DWS的PL/pgSQ

从数仓发展史浅析数仓未来技术趋势

摘要:华为云EI DTSE技术布道师/华为云数仓GaussDB(DWS)首席架构师曾凯,针对数据仓库的起源、演进过程、未来技术发展趋势,与开发者和伙伴朋友们展开交流互动,帮助开发者快速了解数据仓库相关信息与能力。 本文分享自华为云社区《直播回顾 | 从数仓发展史浅析数仓未来技术趋势》,作者:胡辣汤。

浅谈:HTTP 和 HTTPS 通信原理

1.HTTP基本概念 1.1 HTTP是什么? HTTP (超文本传输协议)协议被用于在 Web 浏览器和网站服务器之间传递信息, HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此, HTTP 协议

浅谈k8s中cni0和docker0的关系和区别

最近在复习k8s网络方面的知识,查看之前学习时整理的笔记和文档还有过往自己总结的博客之后发现一个问题,就是在有关flannel和calico这两个k8s网络插件的文章和博客中,会涉及到cni0和docker0这两个网桥设备,但是都没有明确说明他们俩之间的关系,有的甚至将两者混为一谈,这也是我之前的学

浅谈性能测试稳定性 Constant Throughput Timer(常数吞吐量定时器)

在性能测试过程中总会收到一些需求如:单接口每秒并发20,这种并发持续60秒,通过负载测试查看系统稳定性,今天就让我们来浅谈一下这种场景如何去实现性能测试~

浅谈如何向上管理

最近听说了很多事,加之目前自己也处在被汇报以及需要向上汇报的状态中间,迫使我开始思考向上管理(managing up)这个话题。这是一个有争议的话题,很多人(包括曾经的自己)下意识的会将向上管理与徒有其表的讨好或者迎合这类负面词划上等号。借此契机在查阅了很多资料之后,才意识到它不过是一项职场软技能而已。

[转帖]浅谈系统稳定性与高可用保障的几种思路

https://segmentfault.com/u/dewujishu 一、前言 高并发、高可用、高性能被称为互联网三高架构,这三者都是工程师和架构师在系统架构设计中必须考虑的因素之一。今天我们就来聊一聊三H中的高可用,也是我们常说的系统稳定性。 本篇文章只聊思路,没有太多的深入细节。阅读全文大概

[转帖]浅谈RAID写惩罚(Write Penalty)与IOPS计算

介绍 通常在讨论不同RAID保护类型的性能的时候,结论都会是RAID-1提供比较好的读写性能,RAID-5读性能不错,但是写入性能就不如RAID-1,RAID-6保护级别更高,但写性能相对更加差,RAID10是提供最好的性能和数据保护,不过成本最高等等。其实决定这些性能考虑的因素很简单,它就是RAI

[转帖]浅谈RAID写惩罚(Write Penalty)与IOPS计算_文字版

https://www.cnblogs.com/IvanChen/p/4491984.html 介绍 通常在讨论不同RAID保护类型的性能的时候,结论都会是RAID-1提供比较好的读写性能,RAID-5读性能不错,但是写入性能就不如RAID-1,RAID-6保护级别更高,但写性能相对更加差,RAID

[转帖]张磊:浅谈容器网络

https://zhuanlan.zhihu.com/p/595014129 你好,我是张磊。今天我和你分享的主题是:浅谈容器网络。 在前面讲解容器基础时,我曾经提到过一个Linux容器能看见的“网络栈”,实际上是被隔离在它自己的Network Namespace当中的。 而所谓“网络栈”,就包括了