oracle

关注公众号 jb51net

关闭
首页 > 数据库 > oracle > OraclePL/SQL存储过程

Oracle在PL/SQL中使用存储过程

作者:springsnow

这篇文章介绍了Oracle在PL/SQL中使用存储过程的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

一、概述

过程和函数统称为PL/SQL子程序,他们是被命名的PL/SQL块,均存储于数据库中。

并通过输入、输出和输入输出参数与其调用者交换信息。唯一区别是函数总向调用者返回数据。

二、存储过程详解

1、创建过程语法:

CREATE [ OR REPLACE ] PROCEDURE [ schema. ] procedure_name
    [ ( parameter_declaration [, parameter_declaration ]... ) ]
    [ invoker_rights_clause ]
    { IS | AS }
    { [ declare_section ] body | call_spec | EXTERNAL} ;

说明:

parameter_name [ [ IN ] datatype [ { := | DEFAULT } expression ]
          | { OUT | IN OUT } [ NOCOPY ] datatype
AUTHID { CURRENT_USER | DEFINER }

2、创建存储过程

带有输入、输出参数的过程

CREATE OR REPLACE PROCEDURE proc_demo
(
    dept_no NUMBER DEFAULT 10,
    sal_sum OUT NUMBER,
    emp_count OUT NUMBER
  )
IS
BEGIN
    SELECT SUM(salary), COUNT(*) INTO sal_sum, emp_count
  FROM employees WHERE department_id = dept_no;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('温馨提示:你需要的数据不存在!');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END proc_demo;

3、调用存储过程

调用方式: 
1)、当在SQL*PLUS中调用过程时,需要使用CALL或者EXECUTE命令,而在PL/SQL块中过程可以直接引用。

-- 调用删除员工的过程
EXEC remove_emp(1);
  
-- 调用插入员工的过程
EXECUTE insert_emp(1, 'tommy', 'lin', 2);

2)、在PL/SQL语句块中直接调用。

DECLARE
V_num NUMBER;
V_sum NUMBER(8, 2);
BEGIN
  Proc_demo(30, v_sum, v_num);
     DBMS_OUTPUT.PUT_LINE('温馨提示:30号部门工资总和:'||v_sum||',人数:'||v_num);
  Proc_demo(sal_sum => v_sum, emp_count => v_num);
     DBMS_OUTPUT.PUT_LINE('温馨提示:10号部门工资总和:'||v_sum||',人数:'||v_num);
END;

4、C# 调用:

OracleCommand cmd = new OracleCommand("prroc_demo", myOracleConnection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("v_companycode", OracleType.Char); 
cmd.Parameters["v_companycode"].Value = "aa";
cmd.Parameters.Add("v_returnvalue", OracleType.Float).Direction = ParameterDirection.Output;
cmd.ExecuteNoQuery();
string eval = cmd.Parameters["v_returnvalue"].Value.ToString();

三、存储过程返回记录集SYS_REFCURSOR

cursor与REF cursor大致有以下几点区别:

1、返回单行语法

create or replace procedure proc_query_rent (
  param_region varchar2,  --定义区
  param_room number,  --定义室
  param_hall number,  --定义厅
  param_rentMin number,  --定义租金上限
  param_rentMax number,  --定义租金下限
  param_resultSet OUT SYS_REFCURSOR --定义out参数返回结果集
) 
as 
begin 
open param_resultSet for select  * from tb_rent
 where region like case when param_region IS null then '%' else param_region end
  AND room like case when param_room IS null then '%' else to_char(param_room) end
  AND hall like case when param_hall IS null then '%' else to_char(param_hall) end
  AND rent between case when param_rentMin IS null then 0 else param_rentMin end
  AND case when param_rentMax IS null then 99999999 else param_rentMax end;
end;

调用:

declare 
  v_rent_rows SYS_REFCURSOR;
  v_rent_row tb_rent % rowType;
begin 
   proc_query_rent('山区', null, null, 1200, null, v_rent_rows);
   Dbms_output.put_line('所在区 室 厅 租金');
   loop 
      fetch v_rent_rows into v_rent_row;//单行
      exit when v_rent_rows % NOTFOUND;
      Dbms_output.put_line(v_rent_row.region || '  ' || v_rent_row.room || '  ' || v_rent_row.hall || '  ' || v_rent_row.rent);
   end loop;
   close v_rent_rows;
end;

2、返回多行语法

存储过程:

create or replace procedure getEmpByDept(in_deptNo in emp.deptno%type,  out_curEmp out SYS_REFCURSOR) as 
begin 
 open out_curEmp for 
  SELECT * FROM emp WHERE deptno = in_deptNo ; 
EXCEPTION 
 WHEN OTHERS THEN 
 RAISE_APPLICATION_ERROR(-20101, 
  'Error in getEmpByDept' || SQLCODE ); 
end getEmpByDept;

调用(执行存储过程):

declare 
  cur_emp sys_refcursor;
  type emp emp_type is table of yemp%rowtype;
  vemps emp_type;
begin
   sp_getEmp(line=>'A5',curemp=>cur_emp);
   fetch cur_emp bulk collect into vemps;
   for i in v_emps.first..v_emps.last loop
      dbms_output.putline(v_emps(i).empid);
   end loop;
   close cur_emp;
end;

C# 调用:

OracleCommand cmd = new OracleCommand("prroc_demo", myOracleConnection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("v_companycode", OracleType.Char).Value = "aa";
cmd.Parameters.Add("curEmp", OracleType.Cursor).Direction = ParameterDirection.Output;
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
this.dataGridView1.DataSource = ds.Tables[0];

四、维护存储过程

1、删除过程

可以使用DROP PROCEDURE命令对不需要的过程进行删除

DROP PROCEDURE logexecution;

2、显示过程代码

select text from user_source where name='存储过程名(大写)' and type='PROCEDURE';

3、查看过程状态

select  object_type ,object_name ,status from user_objects where  object_name  = 'procedure';

4、重新编译过程

alter procedure pro_backup compile;

五. 过程与函数比较

1、相同点:

2、不同点:

六、 与过程相关数据字典

USER_SOURCE, ALL_SOURCE, DBA_SOURCE, USER_ERRORS,

ALL_PROCEDURES,USER_OBJECTS,ALL_OBJECTS,DBA_OBJECTS

相关的权限:

CREATE ANY PROCEDURE

DROP ANY PROCEDURE

SQL*PLUS 中,可以用DESCRIBE 命令查看过程的名字及其参数表。

DESC[RIBE] Procedure_name;

到此这篇关于Oracle在PL/SQL中使用存储过程的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文