zoukankan      html  css  js  c++  java
  • 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名称。

  • 相关阅读:
    磁盘相关命令
    shell $用法
    setuid setgid stick bit 特殊权限 粘滞位
    运维面试题2
    mysql 外键约束
    创建MySQL 用户
    shell 脚本定时创建月份表
    apache 配置多个虚拟主机,不同的端口
    sublime3中文乱码解决包ConvertToUTF8.zip
    yii2安装
  • 原文地址:https://www.cnblogs.com/qianlang/p/11684566.html
Copyright © 2011-2022 走看看