Oracle存储过程4 -- 存过的类比理解

版权声明:原创转载请注明出处,谢谢 https://blog.csdn.net/qq_21108311/article/details/89010607

DBA时间做长了,难免会涉及到一些其他的小功能开发,写写python啊、Java啊之类,回过头来,再看下数据库开发,突然觉得存过理解清晰了许多。

 

我是这样类比的,对于业务需求,假设我们使用python开发一个需求,那么在包的下层,肯定是写的业务方法,根据python的方法传参写法:

def A(x,y):
    
    return

总结下来,实现一个方法的开发,格式是声明一个函数(方法),同时声明一个对接外部的参数(如果需要接受数据),最后返回一个方法值(如果需要返回值时);

同样,我们看看Java方法的一般写法:

public static void A(int x){


retrun
}

在python的方法中有x,y参数作为接受外部传递过来的数据,使方法内部能够调用处理外部数据,同样Java中A方法括号里面x也是接收外来的数据,使方法内部能够使用。

反过来看Oracle存过,结构也是一样的:

create or replace procedure A(B in varchar,C out integer,D out SYS_REFCURSOR)

可以类比成方法A里面有B,C,D三个参数用来进行对外数据的交互,性质上微小差异是,py/java返回值的时后,方法本身不需要一个承接结果的变量(调用方法处可能需要),而Oracle返回值时需要有一个变量进行数据接受,因此这里区分in类型变量和out类型变量,in类型负责接受,out负责传出,若不需要传出可以不要out类型参数。(这些话仅是帮助类比理解存过结构,具体知识体系需自行深入学习)

 

通过以上类比,学过开发的同学,就会快速理解存过,就像是一种:定义方法名 + 传参变量 + 方法计算体 + 返回值  的结构,清晰简单


接下来聊聊计算体的内容,

方法计算体写法一般都是根据业务需求来写的逻辑,所以这没什么好说的,按照业务写就行了

这里常用的无非就是两:

1、外部数据切分

2、数据循环

因为传过来的数据不一定是你所想要的格式,所以有时候会涉及到数据切分。

这里,一定要强行要求传递过来的数据结构要一致,否则切分会出问题,数据库属于系统底层,一旦数据异常可能引起该数据相关的服务都会产生异常,最后坑的还是DBA,所以外部给数据的时候,一定要定义好相关格式,即使为空也要传相关参数。

py里面有split等参数,Oracle里面可以按照instr参数进行数据切分

 

切分成为单体数据之后,在计算体内就可以定义一堆变量承接这些切分的数据就可以去处理了

循环可用for/loop等,这个自行查询了

一般带参数的sql在存过中想执行,需要用动态语句,EXECUTE IMMEDIATE,具体用法请自行查询

经验分享:

EXECUTE IMMEDIATE sql INTO 变量;把执行的sql结果赋值给变量,这里是单体赋值,即只能返回一个值

多值返回,比如想返回一个查询结果的视图集合,需要定义传出参数类型为游标类型,即

PROCEDURE 存过名(参数变量B OUT SYS_REFCURSOR),这里B后边的out类型要跟上SYS_REFCURSOR,定义成游标

在计算体最后返回值的时候,用OPEN B FOR(计算sql); 返回计算sql中的多值给B,如果直接是out类型默认是单值,无法返回多值。

一个数据切分小技巧:

技巧1:

instr切分数据可以把他做成一个函数(和存过区别是有返回值),就可以多次调用切分拉,超级方便

做成一个函数后,因为带有返回值,返回值类型要存多值的,所以定义返回值参数类型需要为Array类型

技巧2:

对于一个变量想全局使用时有统一的一个自定义类型,可以在同一个用户下创建一个type,这里创建的type可以指定成想要的数据类型,例如我想定义A时Array类型,则我可以create type A为Array类型,之后我在相同用户下使用A默认就是array类型的变量

以上连个小技巧,看不懂的没关系,存过写多了就懂了 

 

当然,建议不要用多值传参的形式给到数据库计算,能推就推,本来就是开发的事情,非要给到数据库实现,数据库本身又难于扩展,除了开发实力low以外,是在想不到什么理由喜欢把业务丢数据库来

展开阅读全文

没有更多推荐了,返回首页