Oracle PLSQL 存储过程

1、PLSQL中的存储过程

1,在PLSQLDEVELOPER中开发存储过程

File->New->Program Window->Procedure
image.png

2,PLSQL存储过程的参数模式

IN OUT IN OUT
默认模式 必须显式指定 必须显式指定
用以把值传给过程 用以把值从过程 返回给调用环境 用以把变量传递给过 程,并返回给调用环境
参数可以是常数、变量、表达式 必须是个变量 必须是个变量
可以赋予默认值 不能赋予默认值 不能赋予默认值
  1. CREATE OR REPLACE PROCEDURE query_emp
  2. (p_id IN employees.employee_id%TYPE,
  3. p_name OUT employees.last_name%TYPE,
  4. p_salary OUT employees.salary%TYPE,
  5. p_comm OUT employees.commission_pct%TYPE)
  6. IS
  7. BEGIN
  8. SELECT last_name, salary, commission_pct
  9. INTO p_name, p_salary, p_comm
  10. FROM employees
  11. WHERE employee_id = p_id;
  12. END query_emp;
  13. /
  1. CREATE OR REPLACE PROCEDURE format_phone
  2. (p_phone_no IN OUT VARCHAR2)
  3. IS
  4. BEGIN
  5. p_phone_no := '(' || SUBSTR(p_phone_no,1,3) ||
  6. ')' || SUBSTR(p_phone_no,4,3) ||
  7. '-' || SUBSTR(p_phone_no,7);
  8. END format_phone;
  9. /

3,参数传递方式(按顺序传递或者使用=>符号传递)

A.顺序传递

  1. CREATE OR REPLACE PROCEDURE add_dept
  2. (p_name IN departments.department_name%TYPE
  3. DEFAULT 'unknown',
  4. p_loc IN departments.location_id%TYPE
  5. DEFAULT 1700)
  6. IS
  7. BEGIN
  8. INSERT INTO departments(department_id,
  9. department_name, location_id)
  10. VALUES (departments_seq.NEXTVAL, p_name, p_loc);
  11. END add_dept;
  12. /

B.使用=>符号传递

  1. BEGIN
  2. add_dept; #使用默认值
  3. add_dept ('TRAINING', 2500); #按顺序传递
  4. add_dept ( p_loc => 2400, p_name =>'EDUCATION'); #使用=>符号传递,无
  5. 顺序要求
  6. add_dept ( p_loc => 1200) ;
  7. END;
  8. /
  9. SELECT department_id, department_name, location_id
  10. FROM departments;

4,过程调用的例外处理

image.png

5,删除储存过程

  1. DROP PROCEDURE procedure_name

2、PLSQL中的存储函数

1,定义存储函数的语法

  1. CREATE [OR REPLACE] FUNCTION function_name
  2. [(parameter1 [mode1] datatype1,
  3. parameter2 [mode2] datatype2,
  4. . . .)]
  5. RETURN datatype
  6. IS|AS
  7. PL/SQL Block;
  1. CREATE OR REPLACE FUNCTION get_sal
  2. (p_id IN employees.employee_id%TYPE)
  3. RETURN NUMBER
  4. IS
  5. v_salary employees.salary%TYPE :=0;
  6. BEGIN
  7. SELECT salary
  8. INTO v_salary
  9. FROM employees
  10. WHERE employee_id = p_id;
  11. RETURN v_salary;
  12. END get_sal;
  13. /

2,使用PLSQLDeveloper 开发函数

image.png

3,可以使用用户自定义的函数的SQL语句

  • select 语句
  • Where条件和Having子句
  • CONNECT BY, START WITH, ORDER BY, 和GROUP BY 子句
  • INSERT的Values子句
  • UPDATE的Set子句

    1. SELECT employee_id, tax(salary)
    2. FROM employees
    3. WHERE tax(salary)>(SELECT MAX(tax(salary))
    4. FROM employees WHERE department_id = 30)
    5. ORDER BY tax(salary) DESC;

    4,对于用户定义函数在SQL语句中使用的限制

  • 必须是个函数(不能是过程-Procedure)

  • 只能用IN 模式的参数(不能有OUT, IN OUT 模式的参数)
  • 只能接收SQL数据类型的参数,不能接收PLSQL 中特有的参数(比如记录、PLSQL内 存表)
  • 函数返回的数据类型也必须是有效的数据类型,而不能是PLSQL特有的数据类型
  • 在SQL中使用的函数,其函数体内部不能有DML语句。
  • 在UPDATE/DELETE语句中调用的函数,其函数体内部不能有针对同一张表的查询语句
  • 在SQL中调用的函数,其函数体内部不能有事务结束语句(比如Commit,Rollback)
  1. CREATE OR REPLACE FUNCTION dml_call_sql (p_sal NUMBER)
  2. RETURN NUMBER IS
  3. BEGIN
  4. INSERT INTO employees(employee_id, last_name, email,
  5. hire_date, job_id, salary)
  6. VALUES(1, 'employee 1', 'emp1@company.com',
  7. SYSDATE, 'SA_MAN', 1000);
  8. RETURN (p_sal + 100);
  9. END;
  10. /

5,删除储存函数

  1. DROP FUNCTION function_name

3、函数过程对数据访问的权限概念

定义者权限和调用者权限
image.png

1,定义者权限

函数执行时,对表的访问默认使用定义者权限

2,调用者权限

在写函数的时候有特殊语句标识:AUTHID CURRENT_USER

  1. CREATE PROCEDURE query_emp
  2. (p_id IN employees.employee_id%TYPE,
  3. p_name OUT employees.last_name%TYPE,
  4. p_salary OUT employees.salary%TYPE,
  5. p_comm OUT employees.commission_pct%TYPE)
  6. AUTHID CURRENT_USER
  7. IS
  8. BEGIN
  9. SELECT last_name, salary,
  10. commission_pct
  11. INTO p_name, p_salary, p_comm
  12. FROM employees
  13. WHERE employee_id=p_id;
  14. END query_emp;
  15. /