
【我和openGauss的故事】带有out参数的存储过程及自定义函数的重载测试
背景
先说下数据库里说的函数重载是什么。比如我们知道数据库可能会有同名的函数,但是函数的参数声明不一样
上面这种情况就叫函数的重载,虽然函数名一致,但实际在数据库中对应的是不同的函数。
在ORACLE中,本身并不支持同名对象,ORACLE中的函数重载,基本都是在PACKAGE中实现的,比如上面的to_char函数,其实是在一个名为"STANDARD"的PACKAGE中。
然后在ORACLE中,对于是否重载的判断,会同时考虑出入参的个数和类型,因此支持这样的重载
而在openGauss中,支持在非package中重载存储过程,默认情况是只考虑存储过程名称以及入参的匹配,即上述两个同名存储过程由于都是有两个入参,且类型一致,会被识别为同一个存储过程,即不能重载。
不过,在openGauss中,有参数来控制是否支持重载
相关参数
官方文档:https://docs.opengauss.org/zh/docs/5.0.0/docs/DatabaseReference/%E5%B9%B3%E5%8F%B0%E5%92%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%85%BC%E5%AE%B9%E6%80%A7.html
官方文档中,对此参数的说明为
控制存储过程出参的重载行为,打开该参数后,对于存储过程只有out出参部分不同的情况下,也可以正常调用。
结合我上面提到的那个重载的例子,这段话就好理解了。
但是,实际上proc_outparam_override这个选项不仅如此
测试
一、创建
A、package外的procedure
1.关闭选项,创建in参数一致但out参数不一致的同名procedure,报错
2.用create or replace procedure,会直接覆盖同名procedure
3.创建同名,但in参数类型不一致的procedure,发现也会将之前同名的procedure覆盖掉
4.打开选项后,上述测试结果不会发生变化
B、package外的function(ORACLE语法风格)
1.关闭选项,创建in参数一致但out参数不一致的同名function,报错
2.用create or replace function ,会直接覆盖同名function
3.创建同名,但in参数类型不一致的function,发现也会将之前同名的function覆盖掉
4.打开选项后,上述测试结果不会发生变化
C、package外的function(PG语法风格)
1.关闭选项,创建in参数一致但out参数不一致的同名function,报错
2.用create or replace function ,会直接覆盖同名function
3.创建同名,但in参数类型不一致的function,此时不会覆盖原有同名函数
4.打开选项后,上述测试结果不会发生变化
D、PACKAGE内的procedure
1.关闭选项,入参一致,出参不一致的同名procedure,创建报错
2.打开选项,再次创建,不报错
3.关闭选项,入参类型不一致,出参一致,创建成功(打开参数时,情况一样)
4.特殊情况1,procedure的名称和入参的自定义复合类型中的一个属性名一致时,会报错(此处与重载无关)
5.特殊情况2,带inout的参数,在关闭重载选项时,只会判断in的参数个数,不会判断参数的数据类型,一个inout参数相当于一个in参数和一个out参数,下例两个procedure都只有一个in参数,因此创建报错;但打开重载选项后,可以创建成功,此时inout视为一个参数,判断重复的规则变成了 “存储过程名称+总参数个数+按相同顺序的参数inout类型+按相同顺序参数数据类型”
E、PACKAGE内的function
1.关闭选项,入参一致,出参不一致的同名function,创建报错
2.打开选项,再次创建,报错发生变化
3.关闭选项,入参类型不一致,出参一致,创建成功(打开选项时,情况一样)
二、使用
PLSQL block中使用
1.开启重载选项,调用package中的procedure,重载的procedure均可正常获取出参
2.关闭选项,调用包内带出参的procedure (无重载的情况),可正常获取出参
3.开启选项,调用包内带出参的函数,出参可正常获取
4.关闭选项,调用包内带出参的函数,无法获得out参数的值
SQL中使用
1.关闭重载选项,使用select 方式调用package中的procedure,传参只能传in参数,不能传out参数(带默认值的in参数可以不传)
2.打开重载选项,使用select 方式调用package中的procedure,必须传满in和out参数,out参数只需要传对类型,值无实际意义(带默认值的in参数可以不传)
3.获取多个out参数的方法
4.关闭重载选项,使用select 方式调用带出参的package内function
5.打开重载选项,使用select 方式调用带出参的package内function
总结
对于openGauss
一、以下两条不会由于重载选项的差异发生行为改变
1.使用ORACLE风格语法的procedure和function,创建规则和ORACLE一致,同名对象直接覆盖
2.使用PG风格的FUNCTION,支持入参不一致的重载创建;对于入参一致,仅出参有差异的,会直接覆盖(如果return类型变化,创建会报错)
二、重载选项会控制package中的procedure能否创建仅出参不一致的重载,关闭选项时,重载规则为仅入参不匹配;开启选项时,重载规则为任意参数不匹配。
三、当有inout参数时,关闭重载选项,视为一个in参数和一个out参数,并且不再判断参数类型差异,重载必须要求入参个数不一致;开启重载选项时按上一条规则,即任意参数不匹配即可重载。
四、打开重载选项时,PLSQL中调用PROCEDURE和FUNCTION方法和ORACLE一致,均可正常获取出参的值;关闭重载选项时,调用FUNCTION无法获得出参的值。
五、打开重载选项时,使用SQL查询procedure和function,需要传满参数,包括所有的in和out参数;关闭重载选项时,只需要传in和inout参数。
文章转载自公众号:openGauss
