总结建立包的步骤

需要建立两部分

建立包的说明

createor replace package EMPLOYEE_PKG

as
procedure 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 IS
BEGIN
  trancount := trancount + 1;
END incTrancount;
PROCEDURE decTrancount IS
BEGIN
  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; 

Procedure0或多个参数,参数可是(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) is

begin
OPEN RC1 FOR
select 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 d
where a.zgbhao00=c.zgbhao00(+) and
a.zgbhao00=d.zgbhao00(+) and   a.nyue0000=d.nyue0000(+) and
  a.zgbhao00=b.zgbhao00(+)   and    a.zgbhao00=gh ; 
  end pro_shuijs;