【Oracle】PL/SQL——存储函数和过程

前端之家收集整理的这篇文章主要介绍了【Oracle】PL/SQL——存储函数和过程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

ORACLE 提供可以把 PL/sql 程序存储在数据库中,并可以在任何地方来运行它。这样就叫存储过程或函数

过程和函数统称为 PL/sql 子程序,他们是被命名的 PL/sql 块,均存储在数据库中,并通过输入、输出参数或输入/输出参数与其调用者交换信息。

过程和函数的唯一区别是函数总向调用者返回数据,而过程则不返回数据。

存储函数

创建存储函数

语法:

CREATE [OR REPLACE] FUNCTION function_name
[ (argment [ { IN | IN OUT }] Type,
argment [ { IN | OUT | IN OUT } ] Type ]
[ AUTHID DEFINER | CURRENT_USER ] --注1
RETURN return_type
{ IS | AS }
<类型.变量的说明>
BEGIN
FUNCTION_body
EXCEPTION
其它语句
END;

说明:
1) OR REPLACE 为可选。有了它,可以或者创建一个新函数或者替换相同名字的函数,而不会出现冲突;

2) 函数名后面是一个可选的参数列表,其中包含 IN、OUT 或 IN OUT 标记。参数之间用逗号隔开。

IN 参数:标记表示传递给函数的值在该函数执行中不改变;

OUT 参数:标记表示一个值在函数中进行计算并通过该参数传递给调用语句;

IN OUT 参数:标记表示传递给函数的值可以变化并传递给调用语句。

若省略标记,则参数隐含为 IN 。

3) 因为函数需要返回一个值,所以 RETURN 包含返回结果的数据类型。

例子:

  1. --创建一个存储函数
  2. --定义一个函数获取给定部门的工资总和与该部门员工总数
  3. --要求:部门号定义为参数,工资总额定义为返回值
  4. CREATE OR REPLACE FUNCTION GET_SAL_FUN(DEPT_ID NUMBER,TOTAL_COUNT OUT NUMBER)
  5. RETURN NUMBER
  6. IS
  7. --函数使用过程中,需要声明的变量、记录类型、cursor
  8. V_SUM_SAL NUMBER(10) := 0;
  9. CURSOR SAL_CURSOR IS SELECT E.SALARY FROM EMPLOYEES E WHERE E.DEPARTMENT_ID = DEPT_ID;
  10. BEGIN
  11. TOTAL_COUNT := 0;
  12. --函数的执行体
  13. FOR C IN SAL_CURSOR LOOP
  14. V_SUM_SAL := V_SUM_SAL + C.SALARY;
  15. TOTAL_COUNT := TOTAL_COUNT + 1;
  16. END LOOP;
  17. RETURN V_SUM_SAL;
  18. END;
  19. /
运行之后,在旁边的列表中可以找到对应的函数

函数调用

  1. SET SERVEROUTPUT ON
  2.  
  3. DECLARE
  4. V_NUM NUMBER(5) := 0;
  5. BEGIN
  6. DBMS_OUTPUT.put_line(GET_SAL_FUN(100,V_NUM));
  7. DBMS_OUTPUT.put_line(V_NUM);
  8. END;
  9. /
结果:

其中V_NUM在函数中定义为OUT类型,可以在函数中参与计算后,返回给调用函数的语句。


函数调用的传参格式有三种

第一种:位置表示法


第二种:名称表示法


其中,前面为形参,后面为实参,形参的名称必须与函数定义声明里的参数名称相同,这种方式可以任意排列参数位置。

第三种方式属于第一种和第二种混合使用。


在CREATE OR REPLACE FUNCTION 语句中声明函数参数时,可以使用DEFAULT 关键字为输入参数指定默认值。

存储过程

创建存储过程

存储过程和存储函数差不错,区别在于存储函数有返回值,而存储过程没有返回值。

  1. SET SERVEROUTPUT ON
  2. --创建一个存储过程
  3. --定义一个存储过程:获取给定部门的工资总和(通过out参数)
  4. --要求:部门号,工资总和 定义为参数
  5. CREATE OR REPLACE PROCEDURE GET_SAL_PRO(DEPT_ID NUMBER,SUM_SAL OUT NUMBER)
  6. IS
  7. CURSOR SAL_CURSOR IS SELECT E.SALARY FROM EMPLOYEES E WHERE E.DEPARTMENT_ID = DEPT_ID;
  8. BEGIN
  9. SUM_SAL := 0;
  10. --函数的执行体
  11. FOR C IN SAL_CURSOR LOOP
  12. SUM_SAL := SUM_SAL + C.SALARY;
  13. END LOOP;
  14. DBMS_OUTPUT.put_line(SUM_SAL);
  15. END;
  16. /
结果:


上面主要是查询数据,存储过程也可以用来修改数据

例子:

  1. --自定义一个存储过程,对给定部门(作为输入参数)的员工进行加薪操作,若其到公司的时间在
  2. -- (?, 95)期间,加薪 5%;[9598),加薪3%;[98,?),加薪1%。
  3. -- 输出为此次加薪公司每月需要额外付出多少成本(定义一个OUT型的输出参数)
  4.  
  5. CREATE OR REPLACE PROCEDURE ADD_SALARY(DEPT_ID NUMBER,ADD_TEMP OUT NUMBER)
  6. IS
  7. CURSOR SAL_CURSOR IS
  8. SELECT E.EMPLOYEE_ID,E.HIRE_DATE,E.SALARY FROM EMPLOYEES E WHERE E.DEPARTMENT_ID = DEPT_ID FOR UPDATE;
  9. --加薪比例
  10. R NUMBER(4,2) := 0;
  11. --加薪后的工资
  12. V_NEW_SALR NUMBER(10,2) := 0;
  13. BEGIN
  14. ADD_TEMP :=0;
  15. FOR C IN SAL_CURSOR LOOP
  16. --每次循环初始化
  17. R := 1;
  18. V_NEW_SALR := 0;
  19. --打印最初的值
  20. DBMS_OUTPUT.put_line(C.EMPLOYEE_ID || '-入职日期:' || C.HIRE_DATE || ',加薪前的工资:' || C.SALARY);
  21. IF C.HIRE_DATE < TO_DATE('1995','yyyy')
  22. THEN R := 0.05;
  23. ELSIF C.HIRE_DATE >= TO_DATE('1995','yyyy') AND C.HIRE_DATE < TO_DATE('1998','YYYY')
  24. THEN R := 0.03;
  25. ELSIF C.HIRE_DATE >= TO_DATE('1998','yyyy')
  26. THEN R := 0.01;
  27. END IF;
  28. --计算新增的成本
  29. ADD_TEMP := ADD_TEMP + C.SALARY * R;
  30. --更新数据
  31. UPDATE EMPLOYEES E1 SET E1.SALARY = C.SALARY * (1 + R) WHERE E1.EMPLOYEE_ID = C.EMPLOYEE_ID;
  32. SELECT E2.SALARY INTO V_NEW_SALR FROM EMPLOYEES E2 WHERE E2.EMPLOYEE_ID = C.EMPLOYEE_ID;
  33. --打印改编后的值
  34. DBMS_OUTPUT.put_line('加薪后的工资:' || V_NEW_SALR);
  35. END LOOP;
  36.  
  37. END;
  38. /
存储过程的调用
  1. SET SERVEROUTPUT ON
  2. DECLARE
  3. ADD_TEMP NUMBER(10,2) := 0;
  4. BEGIN
  5. ADD_SALARY(100,ADD_TEMP);
  6. DBMS_OUTPUT.put_line('新增成本:' || ADD_TEMP);
  7.  
  8. END;
  9. /
结果:




注1:

AUTHID

在创建存储过程时,可使用 AUTHID CURRENT_USER 或 AUTHID DEFINER 选项,以表明在执行该过程时Oracle 使用的权限。

1) 如果使用 AUTHID CURRENT_USER 选项创建一个过程,则 Oracle 用调用该 过程的用户权限执行该过程。为了成功执行该过程,调用者 必须具有访问该存储过程体中引用的所有数据库对象所必须的权限;

2) 如果用默认的 AUTHID DEFINER 选项创建过程,则 Oracle 使用过程所有者的特权执行该过程。为了成功执行该过程,过程的所有者 必须具有访问该存储过程体中引用的所有数据库对象所必须的 权限。想要简化应用程序用户的特权管理,在创建存储过程时,一般选择 AUTHID DEFINER选项,这样就不必授权给需要调用的此过程的所有用户了。

猜你在找的Oracle相关文章