设为首页 收藏本站
查看: 881|回复: 0

[经验分享] oracle程序包的原理和使用

[复制链接]

尚未签到

发表于 2016-8-4 12:45:45 | 显示全部楼层 |阅读模式
程序包


程序包的定义:
  程序包是对相关过程、函数、变量、游标和异常等对象的封装
  程序包由规范和主体两部分组成


DSC0000.jpg



优点:
  模块化、更轻松的应用程序设计、信息隐藏、新增功能、性能更佳。


创建包头包体的基本操作如下:
createorreplacepackagepack1--创建包头/规范
is
aanumber:=1;--在包头声明的为公有变量
procedureupdate_student(update_rowinstudent%rowtype);--声明一个更新过程
procedureinsert_student(insert_rowinstudent%rowtype);--声明一个插入过程
endpack1;--结束包头


--Package created


createorreplacepackagebodypack1--创建包体/主体
is
bbnumber:=2;--在包体声明的变量类私有变量
procedureinsert_student(insert_rowinstudent%rowtype)--创建过程主体
as
begin
insertintostudent(id,name,age)values(insert_row.id,insert_row.name,insert_row.age);
dbms_output.put_line('bb = '||bb||'aa = '||aa);
endinsert_student;--结束过程主体

procedureupdate_student(update_rowinstudent%rowtype)--创建过程主体
as
begin
updatestudent ssets.name='赵北'wheres.id=update_row.id;
endupdate_student;--结束过程主体
endpack1;--结束主体/包体


--Warning: Package body created with compilation errors


SQL>showerror;--查询错误
ErrorsforPACKAGEBODYHR.PACK1:
LINE/COLERROR
----------------------------------------------------------------------------
5/1PLS-00103:出现符号"BEGIN"在需要下列之一时:;iswithauthidas
clusterorderusingexternaldeterministicparallel_enable
pipelinedresult_cache 符号 ";" 被替换为 "BEGIN" 后继续。
10/3PLS-00103:出现符号"PROCEDURE"
11/5PLS-00103:出现符号"BEGIN"在需要下列之一时:;iswithauthidas
clusterorderusingexternaldeterministicparallel_enable
pipelinedresult_cache 符号 ";" 被替换为 "BEGIN" 后继续。


SQL>
SQL>ed--修改上次执行的代码块
SQL>/--执行修改的代码块


--Package body created


SQL>setserverouton;--打开输出开关
SQL>executedbms_output.put_line(pack1.aa);--包中的公共变量被输出
1
PL/SQLproceduresuccessfully completed


SQL>executedbms_output.put_line(pack1.bb);--包中的私有变量不被输出

begindbms_output.put_line(pack1.bb);end;
--ORA-06550: 第 1 行, 第 34 列:
--PLS-00302: 必须声明 'BB' 组件
--ORA-06550: 第 1 行, 第 7 列:
--PL/SQL: Statement ignored

declare
row_student student%rowtype;--声明行级变量
begin
row_student.id:=5;
row_student.name:='张飞';
row_student.age:=60;
pack1.insert_student(row_student);--调用包中的过程
end;
/

bb=2aa=1
PL/SQLproceduresuccessfully completed


SQL>select*fromstudent;
IDNAME AGE
----------- -------------------- -----------
1张三20
2李四25
3王五30
4麻子30
5张飞60


SQL>

declare
row_student student%rowtype;--声明行级变量
begin
row_student.id:=5;
row_student.name:='关羽';
row_student.age:=60;
pack1.update_student(row_student);--调用包中的过程
end;
/
PL/SQLproceduresuccessfully completed


SQL>select*fromstudent;
IDNAME AGE
----------- -------------------- -----------
1张三20
2李四25
3王五30
4麻子30
5赵北60



程序包中的游标:
q游标的定义分为游标规范和游标主体两部分
q在包规范中声明游标规范时必须使用RETURN子句指定游标的返回类型
qRETURN子句指定的数据类型可以是:
q用%ROWTYPE属性引用表定义的记录类型
q程序员定义的记录类型,例如TYPE EMPRECTYP IS RECORD(emp_idINTEGER,salaryREAL)来定义的。
q不可以是number, varchar2,%TYPE等类型。

-----------------------------在程序包中创建显示游标---------------
createorreplacepackagepack2--创建包头
is
cursorstudent_cursorreturnstudent%rowtype;--声明显示游标,但是不能跟isselect子句
procedurestudent_pro;--声明过程
endpack2;


createorreplacepackagebodypack2--创建包体
is
cursorstudent_cursorreturnstudent%rowtypeisselect*fromstudent;--指定游标所关联的select
procedurestudent_pro
is
student_row student%rowtype;
begin
openstudent_cursor;
fetchstudent_cursorintostudent_row;
whilestudent_cursor%found
loop
dbms_output.put_line('学号 = '||student_row.id||'姓名 = '||student_row.name);
fetchstudent_cursorintostudent_row;
endloop;
closestudent_cursor;
endstudent_pro;
endpack2;
/


SQL>executepack2.student_pro;
学号=1姓名=张三
学号=2姓名=李四
学号=3姓名=王五
学号=4姓名=麻子
学号=5姓名=赵北
PL/SQLproceduresuccessfully completed


SQL>


-----------------------------在程序包中创建ref游标---------------
createorreplacepackagepack3
is
typeref_cursorisrefcursor;--声明一个ref游标类型
procedureref_student_pro;
endpack3;
--Package created


createorreplacepackagebodypack3
is
procedureref_student_pro
is
student_row student%rowtype;
student_ref_cursor ref_cursor;--声明一个ref游标类型的变量
begin
openstudent_ref_cursorforselect*fromstudent;
fetchstudent_ref_cursorintostudent_row;
whilestudent_ref_cursor%found
loop
dbms_output.put_line('学号 = '||student_row.id||'姓名 = '||student_row.name);
fetchstudent_ref_cursorintostudent_row;
endloop;
closestudent_ref_cursor;
endref_student_pro;
endpack3;


--Package body created


SQL>executepack3.ref_student_pro;
学号=1姓名=张三
学号=2姓名=李四
学号=3姓名=王五
学号=4姓名=麻子
学号=5姓名=赵北
PL/SQLproceduresuccessfully completed


SQL>




系统内置程序包:
--------------------------------DBMS_job包的使用方法:------------------------------------
createtabletest_job(date_signdate);


createorreplaceprocedurepro_test
is
begin
insertintotest_jobvalues(sysdate);
end;

SQL>variablejob1number;
SQL>
SQL>begin
2 dbms_job.submit(:job1,'pro_test;',sysdate,'sysdate+ 1/1440');--Submit()过程,工作被正常地计划好。
3end;
4/
PL/SQLproceduresuccessfully completed
job1
---------
23


SQL>
SQL>begin
2 dbms_job.run(:job1);-- Run()过程用来立即执行一个指定的工作。这个过
程只接收一个参数。


3end;
4/
PL/SQLproceduresuccessfully completed
job1
---------
23


SQL>select*fromtest_job;
DATE_SIGN
-----------
19-1-1523


SQL>select*fromtest_job;
DATE_SIGN
-----------
19-1-1523


SQL>
SQL>begin
2 dbms_job.remove(:job1);--过程来删除一个已计划运行的工作。这个过程接收一个参数。


3end;
4/
PL/SQLproceduresuccessfully completed
job1
---------
23


SQL>



--------------------------------UTL_FILE包的使用方法:------------------------------------


createdirectorydir_utl_fileas'/u01/app/oracle/pl_sql_pacakge/test_utl_file';--创建目录
grantread,writeondirectorydir_utl_filetohr;--给用户赋予权限


createorreplaceprocedurepro_utl_file(path_fileinvarchar2,name_fileinvarchar2)
is
utl_file_contentsvarchar2(2000);--定义内存变量
utl_file_type utl_file.file_type;--定义文件类型变量
begin
utl_file_type:=utl_file.fopen(path_file,name_file,'r',2000);--打开文件
loop
utl_file.get_line(utl_file_type,utl_file_contents);--读取文件内容到内存变量中
dbms_output.put_line(utl_file_contents);--,并打印
endloop;
exception--异常处理部分
whenno_data_found
then
utl_file.fclose(utl_file_type);
end;


Procedurecreated


SQL>setserverouton
SQL>executepro_utl_file('DIR_UTL_FILE','utl_file');
DECLARE
V1VARCHAR2(32767);
F1 UTL_FILE.FILE_TYPE;
BEGIN
-- In this example MAX_LINESIZE is less than GET_LINE's length request
-- so the number of bytes returned will be 256 or less if a line terminator is seen.
F1:=UTL_FILE.FOPEN('MYDIR','MYFILE','R',256);
UTL_FILE.GET_LINE(F1,V1,32767);
UTL_FILE.FCLOSE(F1);


-- In this example, FOPEN's MAX_LINESIZE is NULL and defaults to 1024,
-- so the number of bytes returned will be 1024 or less if a line terminator is seen.
F1:=UTL_FILE.FOPEN('MYDIR','MYFILE','R');
UTL_FILE.GET_LINE(F1,V1,32767);
UTL_FILE.FCLOSE(F1);


-- In this example, GET_LINE doesn't specify a number of bytes, so it defaults to
-- the same value as FOPEN's MAX_LINESIZE which is NULL in this case and defaults to 1024.
-- So the number of bytes returned will be 1024 or less if a line terminator is seen.
F1:=UTL_FILE.FOPEN('MYDIR','MYFILE','R');
UTL_FILE.GET_LINE(F1,V1);
UTL_FILE.FCLOSE(F1);
END;


PL/SQLproceduresuccessfully completed


SQL>


dbms_random的使用:
返回某年内的随机日期,分两步:
1,SELECTTO_CHAR(TO_DATE('01/01/03','mm/dd/yy'),'J')FROMDUAL;
2,SELECTTO_DATE(TRUNC(DBMS_RANDOM.VALUE(2452641,2452641+364)),'J')FROMDUAL;



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-252767-1-1.html 上篇帖子: oracle游标使用的方方面面 下篇帖子: Oracle 11.2.0.3 ORA-12012 ORA-29280 ORA-06512 错误 解决方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表