PLSQL——程序包

  • Post author:
  • Post category:其他




1.程序包概述

程序包是对相关过程、函数、变量、游标和异常等对象的封装

程序包由规范(包头)和主体(包体)两部分组成

规范中可以声明程序包中公共对象。

包括类型、变量、常量、异常、游标规范和子程序规范等

主体中可以声明程序包私有对象和实现在包规范中声明的子程序和游标



2.创建程序包的语法

包头和包体名字一致

程序包规范语法

CREATE [OR REPLACE] PACKAGE 名字 IS|AS
[Public item declarations]
[Subprogram specification]
END [package_name];
create or replace package package_name is/as
Public item declaraions   --公共声明部分
Subprogram specification  --声明PL/SQL子程序
End package_namne         --包的名称

程序包主体

CREATE [OR REPLACE] PACKAGE BODY 名字 IS|AS

[Public item declarations]

[Subprogram bodies]

[BEGIN

Initialization]

END [package_name];

package_name是包的名称

public type and item declarations::私有声明部分

subprogram specificatons:子程序体

如:

--定义包头
create or replace package pack1
is
   aa number := 9;
   procedure insert_dept(v_dept in dept%rowtype);
   function fun(v1 number,v2 number) return number;
end;
--包体实现
create or replace package body pack1
is
bb number := 10;
procedure insert_dept(v_dept in dept%rowtype)
is
begin
   insert into dept values(v_dept.deptno,v_dept.dname,v_dept.loc);

end;

function fun(v1 number,v2 number) return number
is
begin
  return v1 + v2;
end;
end;

调用:包名.元素名;



3.程序包中的游标

游标的定义分为游标规范和游标主体两部分

在包规范中声明游标规范时

必须使用return子句指定游标的返回类型

return 数据类型

;

RETURN子句指定的数据类型可以是:

用 %ROWTYPE 属性引用表定义的记录类型

程序员定义的记录类型,例如 TYPE EMPRECTYP IS RECORD(emp_id INTEGER,salary REAL) 来定义的。

不可以是number, varchar2, %TYPE等类型。

如:

--显示游标
create or replace package pack2 is
  cursor mycursor return emp%rowtype;
  procedure mycursor_use;
end;

create or replace package body pack2 is
  cursor mycursor return emp%rowtype is select * from emp;
  procedure mycursor_use
  is
  v_emp emp%rowtype;
  begin
   open mycursor;
   fetch mycursor  into v_emp;
   while mycursor%found loop
      dbms_output.put_line(v_emp.ename);
      fetch mycursor  into v_emp;
   end loop;
   close mycursor;
  end;
end;
--ref游标
create or replace package pack3 is
  type refcur is ref cursor;
  procedure mycursor_use;
end;


create or replace package body pack3  is
  procedure mycursor_use 
  is
     mycursor refcur;
     v_emp emp%rowtype;
  begin
    open mycursor for select * from emp;
    fetch mycursor  into v_emp;
    while mycursor%found loop
      dbms_output.put_line(v_emp.ename);
      fetch mycursor  into v_emp;
    end loop;
    close mycursor;
  end;
end;



4.内置程序包

	可以扩展数据库的功能

为 PL/SQL 提供对 SQL 功能的访问

用户 SYS 拥有所有程序包

是公有同义词

可以由任何用户访问

一些内置程序包:

DBMS_RANDOM包的的使用

random


用来

产生随机的数字、字符、日期

--产生随机整数 
   SELECT  DBMS_RANDOM.RANDOM FROM DUAL;
	Begin
		dbms_output.put_line(dbms_random.random)
End;
--产生一个100以内的随机整数 
   SELECT ABS(MOD(DBMS_RANDOM.RANDOM,100)) FROM DUAL; 
--VALUE函数会返回一个大于等于0但是小于1的数
例如:
    SELECT DBMS_RANDOM.VALUE FROM DUAL; 

对于指定范围内的数,要加入参数low_value和

high_value


--0到100之间的小数
  SELECT  DBMS_RANDOM.VALUE(0, 100)  
FROM  DUAL; 
--产生0到100之间的整数
   SELECT TRUNC(DBMS_RANDOM.VALUE(0, 100)) 
FROM  DUAL;


STRING函数生成随机文本字符串

,可以指定字符串的类型和所希望的长度。

SELECT DBMS_RANDOM.STRING(‘A’, 20) FROM DUAL;

下面是一些类型的代码:

  1. ‘U’用来生成大写字符,upper
  2. ‘L’用来生成小写字符,lower
  3. ‘A’用来生成大小写混合的字符,
  4. ’P’ 表示 字符串由任意可打印字符构成, ±#$%^^
  5. ’X’表示字符串由大写字符和数字构成。

返回某年内的随机日期,分两步:

–日期对应的内部整数,用格式’J’ -4712

1SELECT TO_CHAR(TO_DATE('01/01/21','mm/dd/yy'),'J') FROM DUAL; 
2,  SELECT TO_DATE(TRUNC(DBMS_RANDOM.VALUE(2459216,2459216+365)),'J')  FROM DUAL; 



DBMS_Job包的用法

--创建测试表
create table mytable1(a date);
--创建一个自定义过程
create or replace procedure test1
is
begin
  insert into mytable1 values(sysdate);
end;

declare
  v number;
begin
  ----创建job
Dbms_job.submit()
/* submit()参数:
1 job     OUT BINARY_INTEGER, 输出的no 编号
2 what      IN  VARCHAR2,'存储过程名;' 
3 next_date IN  DATE DEFAULT sysdate,执行任务的时间
4 interval  IN  VARCHAR2 DEFAULT 'null', 间隔时间 单位是1天*/
dbms_job.submit(v,'test1;',sysdate,'sysdate+1/1440');
  --运行JOB
  dbms_job.run(v);
  --删除JOB
  dbms_job.remove(v);
end;
--停止任务 
dbms_job.broken(27,true);



UTL_FILE包的用法

directory:目录

--1创建一个oracle的目录:
create or replace directory 目录名称 as '目录的路径';
create or replace directory FILEPATH as 'd:/SQL';

declare
   --声名文件类型的变量
   f utl_file.file_type;
begin

   --1.打开文件utl_file.fopen(创建的directory,文件名,打开方式字符串)打开方式分三种 w:写,r:读,a:追加
   f:=utl_file.fopen('FILEPATH','test.txt','w');
   --2.读或写文件utl_file.put_line(文件类型变量,要写的文件内容)
   utl_file.put_line(f,'a');
   utl_file.put_line(f,'b');
   utl_file.put_line(f,'c');
   utl_file.put_line(f,'d');
   --3.关闭文件utl_file.fclose(文件类型变量)
   utl_file.fclose(f);  
end;
declare
   --声名文件类型的变量
   f utl_file.file_type;
   --声名一个变量保存文件中的一行记录
   str varchar2(200);
begin

   --1.打开文件utl_file.fopen(创建的directory,文件名,打开方式字符串)打开方式分三种 w:写,r:读,a:追加
   f:=utl_file.fopen('FILEPATH','test.txt','r');
   --2.读或写文件utl_file.get_line(文件类型变量,读文件内容的变量)
   utl_file.get_line(f,str);
   dbms_output.put_line(str);
     utl_file.get_line(f,str);
   dbms_output.put_line(str);
     utl_file.get_line(f,str);
   dbms_output.put_line(str);
     utl_file.get_line(f,str);
   dbms_output.put_line(str);
   --3.关闭文件utl_file.fclose(文件类型变量)
   utl_file.fclose(f);  
end;
declare
   --声名文件类型的变量
   f utl_file.file_type;
  
begin

   --1.打开文件utl_file.fopen(创建的directory,文件名,打开方式字符串)打开方式分三种 w:写,r:读,a:追加
   f:=utl_file.fopen('FILEPATH','test.txt','r');
   --2.读或写文件utl_file.get_line(文件类型变量,读文件内容的变量)
   loop
     declare
        --声名一个变量保存文件中的一行记录
        str varchar2(200);
     begin
        utl_file.get_line(f,str);
        dbms_output.put_line(str);
        exception
           when no_data_found then
             exit;    
     end;
   end loop;
   --3.关闭文件utl_file.fclose(文件类型变量)
   utl_file.fclose(f);  
end;



版权声明:本文为m0_72036727原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。