总结建立包的步骤
需要建立两部分
建立包的说明
createor replace package EMPLOYEE_PKGasprocedure PRINT_ENAME;end EMPLOYEE_PKG;
建立包体
CREATEOR REPLACE PACKAGE BODY employee_pkg as Procedure print_ename is Begin
Dbms_output.put_line('ss');End print_ename;End employee_pkg;
包的其他例子
CREATEOR REPLACE PACKAGE globalPkg AUTHID CURRENT_USER AS/* The following are T/SQL specific global variables. */ identity INTEGER; trancount INTEGER := 0; TYPE RCT1 IS REF CURSOR;/*new weakcursor definition*/ PROCEDURE incTrancount; PROCEDURE decTrancount;END globalPkg;CREATE OR REPLACE PACKAGE BODY globalPkg AS/* This is a dummy package body added by the migration workbench in order to emulate T/SQLspecific global variables. */PROCEDURE incTrancount ISBEGIN trancount := trancount + 1;END incTrancount;PROCEDURE decTrancount ISBEGIN trancount := trancount - 1;END decTrancount;END globalPkg;
(一) 过程的定义:
这些命名的PL/SQL块成为存储过程和函数,他们的集合、称为程序包。
存储过程
· 存储于数据库中的函数,过程是数据库对象。叫存储过程
· 存储过程经编译和优化后存储在数据库服务器中,使用时只要调用即可
我们可以命名我们的PL/SQL块,并为他们确定参数,存储在数据库中。这样可以从任何数据库客户端或者工具引用和运行他们,比如SQL*PLUS, Pro*C, JDBC。
(二) 优点:
1. 可重用性:一旦命名并保存在数据库中后,任何应用都可以
2. 抽象和数据隐藏..
3. 可保证数据的安全性和完整性。
4. 存储过程的能力大大增强了SQL语言的功能和灵活
性。存储过程可以用流控语句编写,有很强的灵
活性,可以完成复杂的判断和较复杂的运算。
(三) 语法:
CREATE OR REPLACE
PROCEDURE name [ (parameter [,parameter,…] ) ] IS //或AS
[说明:变量定义于此]
BEGIN
执行语句序列
[EXCEPTION
例外处理程序
END [name ];
用户通过create or repalce语句可以建立存储于服务器端的存储过程。存储过程不能用于sql语句。(Procedures cannot be used in SQLstatements; )
Procedure有0或多个参数,参数可是(IN), output (OUT), (IN OUT)
类型.
执行存储过程
set serveroutputon
/
直接执行:
execute my_proc
exec my_proc
(四) 权限:
表和视图具有SELECT, INSERT, UPDATE, DELETE 这样的特权,而过程具有EXECUTE特权。只有将EXECUTE特权赋予用户,用户才可以运行它。而将它赋予PUBLIC用户,则所有用户都可以运行。
其实我们可以将比较复杂的查询写成函数.然后到存储过程中去调用这些函数.
(五) :中的函数与存储过程的区别:
A:函数必须有返回值,而过程没有.
B:函数可以单独执行.而过程必须通过execute执行.
C:函数可以嵌入到SQL语句中执行.而过程不行.
(六) 过程里要返回一个结果集,.就必须要用到游标了!用游标来处理这个结果集.
create or replaceprocedure Test
(
varEmpNameemp.ename%type
)
is begin ------会报错.错误原因没有into子句.
select * from empwhere ename like '%'||varEmpName||'%';
end;
这个程序我们无法用into,因为在Oracle里面没有一个类型去接受一个结果集.这个时候我们可以声明游标对象去接受他.
L/SQL游标:
A:分类:
1:隐式游标:非用户明确声明而产生的游标. 你根本看不到cursor这个关键字.
2:显示游标:用户明确通过cursor关键字来声明的游标.
B:什么是隐式游标:
1:什么时候产生:
会在执行任何合法的SQL语句(DML---INSERTUPDATE DELETE DQL-----SELECT)中产生.他不一定存放数据.也有可能存放记录集所影响的行数.
如果执行SELECT语句,这个时候游标会存放数据.如果执行INSERT UPDATE DELETE会存放记录影响的行数.
C:隐式游标叫什么名字:
名字叫sql
关于sql的游标变量到底有哪些呢?
作用:返回最近一次执行SQL语句所涉及的游标相关信息.因为每执行一次SQL语句,都会产生一个隐式游标.那么当前执行的SQL语句就是当前的隐式游标.
sql%found
sql%notfound
sql%rowcount
sql%isopen
D:关于隐式游标的例子:
create table 学生基本信息表
(
StuID int,
StuName varchar2(20)
)
alter table 学生基本信息表 addconstraint PK_STUID primary key(StuID)
declare
num int:=0;
begin
num:=#
delete from 学生基本信息表where StuID=num;
if sql%notfound then
dbms_output.put_line('该行数据没有发现');
else
dbms_output.put_line('数据被发现并删除,影响的行数为:'||sql%rowcount);
end if;
end;
E:关于显示游标的例子:
1:如何定义显示游标
declare cursor <cursor_name> is[select语句];
declare cursor mycur is selectempno,ename,job from scott.emp;
2:如何打开游标:
open <cursor_name>;
open mycur;
3:如何通过游标来读取数据
fetch <cursor_name> into<variable_list>
4:如何关闭游标:
close <cursor_name>;
close mycur;
注意:在Oracle中,不需要显示销毁游标.因为在Oracle中,很多东西是由JAVA写的.Oracle会自动销毁游标.
5:举例:
declare
cursor mycur is select empno,ename,job fromemp;
vempno emp.empno%type;
vename emp.ename%type;
vjob emp.job%type;
begin
open mycur;
fetch mycur into vempno,vename,vjob;
dbms_output.put_line('I FoundYou!'||mycur%rowcount||'行');
dbms_output.put_line('读取的数据为'||vempno||' '||vename||' '||vjob);
close mycur;
end;
因为只读出来一条,所以要遍历一下:
declare
cursor mycur is select empno,ename,job fromemp;
vempno emp.empno%type;
vename emp.ename%type;
vjob emp.job%type;
begin
open mycur;
loop
fetch mycur into vempno,vename,vjob;
exit when mycur%notfound;
if mycur%found then
dbms_output.put_line('读取的数据为'||vempno||' '||vename||' '||vjob);
end if;
end loop;
dbms_output.put_line('I FoundYou!'||mycur%rowcount||'行');
close mycur;
end;
6:通常情况下我们在读取表数据的时候,我们需要动态的去查询.所以能不能在Oracle中给游标带参数呢?可以!
1):如何定义带参数的游标:
declare cursor <cursor_name>(参数名称 参数类型描述) is select xxxxx from bbbbb where aaa==???and ccc=???;
2):例子:
游标是一个集合,读取数据有两种方式
第一种方式: open fetch close
第二种方式: for 一但使用了for循环在循环刚刚开始的时候,相当于执行open,在处理循环的时候,相当于执行fetch,
在退出循环的时候,相当于执行了close
declare
cursor query(vnamevarchar) is select empno,ename,job from emp where ename like'%'||vname||'%';
begin
for line inquery('A')
loop
dbms_output.put_line(line.empno||''||line.ename||' '||line.job);
end loop;
end;
实现动态输入:
declare
cursor query(vnamevarchar) is select empno,ename,job from emp where ename like'%'||vname||'%';
name1 varchar(10);
begin
name1:=upper('&name1');
for line in query(name1)
loop
dbms_output.put_line(line.empno||''||line.ename||' '||line.job);
end loop;
end;
使用REF游标:
是一种引用类型,类似于指针。
显式和隐式游标的区别:
尽量使用隐式游标,避免编写附加的游标控制代码(声明,打开,获取,关闭),也不需要声明变量来保存从游标中获取的数据。
REF CURSOR游标:
动态游标,在运行的时候才能确定游标使用的查询。分类:
强类型(限制)REF CURSOR,规定返回类型
弱类型(非限制)REFCURSOR,不规定返回类型,可以获取任何结果集。
TYPE ref_cursor_name IS REF CURSOR[RETURN return_type]
使用REF CURSOR游标:返回结果集合
create or replaceprocedure pro_shuijs(gh in varchar2, RC1 INOUT globalPkg.RCT1) isbeginOPEN RC1 FORselect a.zgbhao00 ,a.xming000,GZHJI000+je000000,nvl(SYBXIAN0,0)+nvl(YBAO0000,0)+nvl(YLBXIAN0,0)+nvl(GJJIN000,0) , je000000 补充保险,a.sdshui00 税金from rlvgzsjx2 a ,rltrsdawhxxb,rltdygzlsb c, rlvwcylgj1 dwhere a.zgbhao00=c.zgbhao00(+) anda.zgbhao00=d.zgbhao00(+) and a.nyue0000=d.nyue0000(+) and a.zgbhao00=b.zgbhao00(+) and a.zgbhao00=gh ; end pro_shuijs;