Oracle中存储过程的使用

Posted 路在脚下

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle中存储过程的使用相关的知识,希望对你有一定的参考价值。

   存储过程是写在数据库中的sql语句,它相比写在后台代码中的sql语句速度更快。因为它只需要连接一次数据库,就可以执行较为复杂的sql,不需要多次连接数据库导致系统性能下降,只需要一次连接数据库,然后在

数据库中执行一系列复杂的sql,因为已经在数据库中执行sql了,所以不用再去连接数据库,执行起来速度更快。

Oracle中存储过程的结构:

创建存储过程:

CREATE OR REPLACE PACKAGE mes_bs_pqc_pkg AS

存储过程方法头:

  procedure query_checktype(p_orgid  number    
                             ,p_rescode varchar2              
                             ,p_msg out nvarchar2
                             ,p_data out sys_refcursor);  

存储过程方法体:

procedure query_checktype(p_orgid  number 
                             ,p_rescode varchar2               
                             ,p_msg out nvarchar2
                             ,p_data out sys_refcursor) is
       p_sql    varchar2(1000);                     
    begin
       p_sql := select b.opcode,b.opdesc from tblres_b t left join tblop2res a on a.rescode = t.rescode and a.orgid = t.orgid
                 left join tblop_b b on b.opcode = a.opcode and b.orgid = a.orgid where t.orgid =||p_orgid|| and t.rescode = ‘‘‘||p_rescode||‘‘‘‘;
       
       open p_data for p_sql;
       p_msg := success;                                          
         EXCEPTION
           WHEN OTHERS THEN
             p_msg := SQLERRM || [||FAILED || ];
             RETURN;     
    end; 

p_sql为变量,用于存放sql

p_data为输出参数,sys_refcursor为参数类型,使用游标输出

 

下面分享一些常见的存储过程写法:

1.执行sql,并且把结果赋给变量

v_opcode     varchar2(120);

execute immediate select opcode from tblop2res where orgid = :1 and rescode = :2
                         into v_opcode
                         using p_orgid,p_rescode;

p_orgid、p_rescode为传入参数,v_opcode为输出结果。


2.传入数组类型的参数,并获取数据中的值

   procedure post_pqc_check_applynew(p_orgid  number
                                    ,p_rcard  nvarchar2
                                    ,p_bgentask  nvarchar2 --是否产生任务
                                    ,p_arr_name mes_vs_prd_pub_pkg.normal_str_array
                                    ,p_arr_value mes_vs_prd_pub_pkg.normal_str_array
                                    ,x_ret_code                OUT VARCHAR2
                                    ,x_ret_msg                 OUT VARCHAR2
                                    ,x_ret_data                OUT SYS_REFCURSOR)                               

p_arr_name,p_arr_value为数组类型的参数

验证两个数组的长度是否一直,不一致则抛出异常:

--传入参数名称与值长度不一致
      IF p_arr_name.count != p_arr_value.count THEN
        x_ret_code := $lf_error_array_length;
        x_ret_msg  := mes_vs_sys_pub_pkg.get_err_desc(x_ret_code);
        RETURN;
      END IF;

 循环获取数组中的数据并赋值给变量:

  TYPE normal_str_array IS TABLE OF VARCHAR2(80) INDEX BY BINARY_INTEGER;  --可变数组

--获取数组中值
 FOR v_i in 1 .. p_arr_name.count LOOP
      IF p_arr_name(v_i) = DSSCODE THEN
        v_dsscode := p_arr_value(v_i);
      ELSIF p_arr_name(v_i) = MODELNAME THEN
        v_model := p_arr_value(v_i);
      ELSIF p_arr_name(v_i) = SHIFTCODE THEN
        v_shiftcode := p_arr_value(v_i);
      ELSIF p_arr_name(v_i) = APPDATE THEN
        v_appdate := p_arr_value(v_i);
      ELSIF p_arr_name(v_i) = APPTIME THEN
        v_apptime := p_arr_value(v_i);
      ELSIF p_arr_name(v_i) = FMLFLAG THEN
        v_fmlflag := to_number(p_arr_value(v_i));
      ELSIF p_arr_name(v_i) = CHKTYPE THEN
       v_ckktype := p_arr_value(v_i);
       ELSIF p_arr_name(v_i) = CHKGROUP THEN
            v_chkgroup := to_number(p_arr_value(v_i));
       ELSIF p_arr_name(v_i) = TORESCODE THEN
            v_torescode := p_arr_value(v_i);
       ELSIF p_arr_name(v_i) = MITEMCODE THEN
            v_mitemcode := to_number(p_arr_value(v_i));
       ELSIF p_arr_name(v_i) = CUSER THEN
            v_cuser := p_arr_value(v_i);
       ELSIF p_arr_name(v_i) = FROMRESCODE THEN
          v_rescode := p_arr_value(v_i);           
       ELSIF p_arr_name(v_i) = TOTEMPLATEID THEN
          v_templateid := p_arr_value(v_i);   
       else
          null;
      end if;
      end loop;

使用Type来定义一个数组:TYPE normal_str_array IS TABLE OF VARCHAR2(80) INDEX BY BINARY_INTEGER;

把normal_str_array 作为一个Table类型。

3.使用游标循环,处理数据                             

declare cursor task_ops is select templateid,opcode,version from tblpqccheckconf where orgid = p_orgid and templateid in (select * 
from table(cast(fn_split(v_templateid,chr(44)) AS ty_str_split))); task_op task_ops%rowtype; begin open task_ops; loop fetch task_ops into task_op; exit when task_ops%notfound; --生成taskid
select genuknum() into v_taskid from dual; begin insert into ro_tasklist(taskid,orgid,formid,version,rescode,piecetype,taskstart,taskstate,sampleno,sampleuser, cuser,cdate,ctime,muser,mdate,mtime,actor,actortype,templateid) values (v_taskid,p_orgid,v_id,task_op.version,v_rescode, to_number(v_fmlflag),1,3,upper(p_rcard),v_cuser,v_cuser,mes_vs_lg_utl_pkg.get_sysdate, mes_vs_lg_utl_pkg.get_systime,v_cuser,mes_vs_lg_utl_pkg.get_sysdate,mes_vs_lg_utl_pkg.get_systime, v_checkiegroup,1,task_op.templateid); EXCEPTION WHEN OTHERS THEN x_ret_code := SQLCODE; x_ret_msg := SQLERRM || [ || v_proc_name || ]; RETURN; END; end loop; close task_ops;

4.在procedure调用其他的procedure

mes_bs_pqc_pkg.save_pqc_record_dtl(p_templateid,p_orgid,p_arrdtl_value(v_i),p_isconfirm,x_ret_code,x_ret_msg,x_ret_data);

 mes_bs_pqc_pkg为package名称,save_pqc_record_dtl为procedure名称。

 

以上是关于Oracle中存储过程的使用的主要内容,如果未能解决你的问题,请参考以下文章

oracle中的存储过程,有啥作用,以及怎么在代码中使用?

oracle创建存储过程时,提示错误是:错误(5,18): PL/SQL: ORA-00947: 没有足够的值?代码如下:

oracle的存储过程

oracle创建存储过程时,提示错误是:错误(5,18): PL/SQL: ORA-00947: 没有足够的值?代码如下:

在使用oracle创建存储过程部分代码: EXCEPTION WHEN NO_DATA_FOUND THEN NULL; WHEN OTHERS THEN RAISE;

oracle存储过程