0%

oracle程序包

定义

  • 程序包是对相关过程,函数,变量,游标和异常等对象等封装
  • 程序包由规范(包头)和主体(包体)两部分组成
    • 包头:声明程序包中公共对象。包括类型、变量、常量、异常、游标规范和子程序规范等
    • 包体:声明程序包私有对象和实现在包规范中声明等子程序和游标
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
--包头
CREATE OR replace package pack1
IS
aa int:=9;
PROCEDURE insert_student(a1 IN student%rowtype);
PROCEDURE update_student(a2 IN student%rowtype);
END pack1;

--包体
CREATE OR replace package body pack1
IS
bb int:=5;
PROCEDURE insert_student(a1 IN student%rowtype)
IS
BEGIN
INSERT INTO student(sno,sname,sage) VALUES (a1.sno,a1.sname,a1.sage);
COMMIT;
dbms_output.put_line(pack1.bb);--测试bb能不能访问
END insert_student;

PROCEDURE update_student(a2 IN student%rowtype)
IS
BEGIN
UPDATE student SET sname=a2.sname WHERE sno=a2.sno;
COMMIT;
END update_student;
END pack1;


--测试访问程序包头变量
EXEC dbms_output.put_line(pack1.aa);
--测试访问程序包头体变量
EXEC dbms_output.put_line(pack1.bb);

测试调用

1
2
3
4
5
6
7
8
declare
a1 student%rowtype;
begin
a1.sno:=7;
a1.sname:='AA';
a1.sage:=27;
pack1.insert_student(a1);
end

优点

  • 模块化
  • 更轻松等程序设计
  • 信息隐藏
  • 新增功能
  • 性能更佳

程序包中等游标

  • 游标定义分为游标规范和游标主体两部分
  • 在包规范中声明游标规范时必须使用return子句指定游标的返回类型
  • return子句指定的类型可以是
    • 用%ROWTYPE属性引用定义的记录类型
    • 程序员定义的记录类型,例如TYPE EMPRECTYPE IS RECORD(emp_id integer ,salary REAL)来定义
    • 不可以是number,varchar2,%TYPE等类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
CREATE OR REPLACE PACKAGE pack2 IS
CURSOR mycursor RETURN test1%rowtype;
PROCEDURE mycursor_use;

END pack2;

CREATE OR REPLACE PACKAGE BODY pack2 IS

CURSOR mycursor RETURN test1%rowtype IS
SELECT
*
FROM
test1;

PROCEDURE mycursor_use IS
stu_rec test1%rowtype;
BEGIN
OPEN mycursor;
FETCH mycursor INTO stu_rec;
WHILE mycursor%found LOOP
dbms_output.put_line(stu_rec.c1 || stu_rec.c2);
FETCH mycursor INTO stu_rec;
END LOOP;

CLOSE mycursor;
END mycursor_use;

END pack2;


set serveroutput on;

exec pack2.mycursor_use;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--ref 游标
CREATE OR REPLACE PACKAGE pack3 IS
TYPE refcur IS REF CURSOR;
PROCEDURE mycursor_use;

END pack3;

CREATE OR REPLACE PACKAGE BODY pack3 IS

PROCEDURE mycursor_use IS
mycursor refcur;
stu_rec test1%rowtype;
BEGIN
OPEN mycursor FOR SELECT
*
FROM
test1;

FETCH mycursor INTO stu_rec;
WHILE mycursor%found LOOP
dbms_output.put_line(stu_rec.c1 || stu_rec.c2);
FETCH mycursor INTO stu_rec;
END LOOP;

CLOSE mycursor;
END mycursor_use;

END pack3;

SHOW ERR;

子程序和程序包的信息

  • user_objects 视图包含用户创建的子程序和程序包信息
1
select * from user_objects t1 where t1.object_type in ('PROCEDURE','FUNCTION','PACKAGE','PACKAGE BODY');

1

  • user_source 视图存储子程序和程序包的源代码

2

内置程序包

  • 扩展数据库功能
  • 为PL/SQL提供对SQL功能的访问
  • 用户SYS拥有所有程序包
  • 是公有同义词
  • 可以由任何用户访问

dbms_job包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
create table a(a date);

create or replace procedure test
as
begin
insert into a values(sysdate);
end;

variable job1 number;
begin
dbms_job.submit(:job1,'test;',sysdate,'sysdate+1/1440');--1440=24 * 60,任务要加分号
end;

begin
dbms_job.run(:job1);
end;

begin
dbms_job.remove(:job1);
end;

DBMS_RANDOM

1
2
3
4
5
6
7
8
9
10
11
select dbms_random.random from dual;
--产生一个100以内的随机整数
select abs(mod(dbms_random.random,100)) from dual;
--产生一个大于等于0但是小于1的数
select dbms_random.value from dual;
--产生0到99之间的小数
select dbms_random.value(0,100) from dual;
--产生0到99之间的整数
select trunc(dbms_random.value(0,100)) from dual;
--生成大小写随机的字符串
select dbms_random.string('A',20) from dual;