Oracle 包详解(package)

1 概述

1. 包的概念
	(1) 模块化的思想,用于分类管理过程(procedure)和函数(function(2) 类似于 Java、Python 等语言中的 类(class)
	
2. 包的组成(程序部署顺序:'先执行包头,再执行包体'(1) 包头:package
	(2) 包体:package body

3. 授权: grant execute on 属主.包名 to 用户1, 用户n;

4. 调用: '属主.包名.存储过程名()''属主.包名.方法名()'
                   
5. 建议
	(1) 数据库中所有的过程(procedure)和函数(function)都要用 package 进行封装:便于管理
	(2) 单个的过程(procedure)和函数(function)建议不超过 3000(3) 每个 package 在 create 时都要带上 '属主'(避免所处位置错误)

2 示例

效果截图示例:用户 hr 调用用户 scott 中的 package,来判断 某表 是否存在于 scott 中

在这里插入图片描述

包头:

CREATE OR REPLACE PACKAGE scott.pkg_public_toolkit IS
   PROCEDURE p_whether_table_exists(i_table_name IN sys.all_tab_comments.table_name%TYPE,
                                    o_flag       OUT VARCHAR2,
                                    o_message    OUT VARCHAR2);

   FUNCTION f_whether_table_exists(i_table_name IN sys.all_tab_comments.table_name%TYPE)
      RETURN VARCHAR2;
END pkg_public_toolkit;
/
GRANT EXECUTE ON scott.pkg_public_toolkit TO hr;

包体:

CREATE OR REPLACE PACKAGE BODY scott.pkg_public_toolkit IS
   -- *********************************************
   -- 功能说明: 判断用户 scott 中是否存在表
   -- 参数说明: i_table_name  表名 
   --           o_flag        程序执行标志,Y:成功,N:失败
   --           o_message     程序执行的描述信息
   -- 修改记录:create by yoyo 2020/10/14
   -- *********************************************
   PROCEDURE p_whether_table_exists(i_table_name IN sys.all_tab_comments.table_name%TYPE,
                                    o_flag       OUT VARCHAR2,
                                    o_message    OUT VARCHAR2) IS
      v_count NUMBER(1);
   BEGIN
      -- 判断依据:用户 scott 中是否存在表
      SELECT COUNT(1)
        INTO v_count
        FROM user_tab_comments ust
       WHERE ust.table_name = upper(i_table_name);
   
      -- 程序执行描述信息
      IF v_count >= 1 THEN
         o_message := '存在';
      ELSE
         o_message := '不存在';
      END IF;
   
      -- 程序执行标识
      o_flag := 'Y';
   EXCEPTION
      WHEN OTHERS THEN
         o_flag := 'N'; -- 执行失败
         dbms_output.put_line(dbms_utility.format_error_backtrace); -- 报错的行号
         dbms_output.put_line(SQLCODE || ' : ' || SQLERRM); -- 报错的编号及内容
   END p_whether_table_exists;

   -- *********************************************
   -- 功能说明: 调用存储过程 p_whether_table_exists 的方法
   -- 参数说明:i_empno   部门编号
   --   返回值: i_table_name  表名
   -- 修改记录:create by yoyo 2020/10/14
   -- *********************************************
   FUNCTION f_whether_table_exists(i_table_name IN sys.all_tab_comments.table_name%TYPE)
      RETURN VARCHAR2 IS
      o_flag    VARCHAR2(2);
      o_message VARCHAR2(100);
   BEGIN
      p_whether_table_exists(i_table_name => i_table_name,
                             o_flag       => o_flag,
                             o_message    => o_message);
      RETURN o_message;
   END f_whether_table_exists;
END pkg_public_toolkit;
/

创建完成后,在 PL/SQL 中也可以找到 Package 的位置:
在这里插入图片描述

3 请注意

1. 授权完成,仅表示 '用户n' 能够 '执行' 该 pkg,
   不能保证 '用户n' 能够查询该 pkg 中的 '对象(如:表)', 如图 3.1

2. package、procedurefunction 声明时 isas 的区别
	(1) 在 package、procedurefunction 及自定义类型 type 时,asis 一样,没区别
	(2) 在声明游标(cursor)时,只能使用 is 而不能使用 as
	(3) 在创建视图(view)时,只能使用 as 而不能使用 is 

3. 规范:package、procedurefunction 在结束时的 end 后面都要带上对应的名字
        只有匿名语句块的 end 后面才不带名字,如:
        begin
           pl/sql 语句;
        end;

图 3.1:用户 hr 查询表 scott.emp 报错

在这里插入图片描述

解决办法:授权
grant select on scott.emp to hr;
revoke select on scott.emp from hr; -- 回收权限。

猜你喜欢

转载自blog.csdn.net/qq_34745941/article/details/109047785
今日推荐