之前学习的PL/SQL块是匿名的,不能将其存储 href="http://storage.it168.com/" target=_blank>.存储到数据库中。 我们可以命名我们的PL/SQL块,并为他们确定参数,存储在数据库中。这样可以从任何数据库客户端或者工具引用和运行他们,比如SQL*PLUS, Pro*C, JDBC。这些命名的PL/SQL块成为存储过程和函数,他们的集合成为程序包。 优点: 1. 可重用性:一旦命名并保存在数据库中后,任何应用都可以 2. 抽象和数据隐藏 3. 安全 href="http://safe.it168.com/" target=_blank>.安全性 过程 存储过程就是命了名的PL/SQL块,可以被赋予参数,存储在数据库中,然后由另一个应用或者PL/SQL例程调用。比如 CREATE PROCEDURE my_proc as BEGIN NULL. END. / 语法: CREATE [OR REPLACE] PROCEDURE procedure_name (参数) IS | AS [PRAGMA AUTONOMOUS_TRANACTION.] --声明自主事务处理。 [本地变量声明] BEGIN 执行语句部分 [EXCEPTION] 错误处理部分 END[name]. / CREATE OR REPLACE PROCEDURE my_proc as -- OR REPLACE BEGIN Dbms_output.put_line(‘Hello, world’). END. / 执行存储过程 set serveroutput on begin my_proc end. / 直接执行: execute my_proc exec my_proc 权限: 表和视图具有SELECT, INSERT, UPDATE, DELETE 这样的特权,而过程具有EXECUTE特权。只有将EXECUTE 特权赋予用户,用户才可以运行它。而将它赋予PUBLIC用户,则所有用户都可以运行。 [试验] 创建3个用户 conn donny/donny create user chris identified by chris. 此时不能连结数据库,不能创建过程 grant connect, resource to chris. create user sean identified by sean. grant connect, resource to sean. create user mark identified by mark. grant connect, resource to mark. 使用mark建立一个过程 conn mark/mark create procedure marks_proc as begin null. end. / 尝试使用chris用户执行这个过程: conn chris/chris exec mark.marks.proc 授权: conn mark/mark grant execute on marks_proc to chris conn chris/chris exec mark.marks_proc 尝试使用sean用户执行这个过程: conn sean/sean exec mark.marks.proc 将execute 授予public用户,使得所有用户都可以执行这个过程 conn mark/mark grant execute on marks_proc to public. conn sean/sean exec mark.marks.proc 参数: 过程可以进行参数化处理,可以为任何合法的PL/SQL类型,有三种模式:IN, OUT, IN OUT IN 参数通过调用者传入,只能由过程读取,不能改变。是默认的模式,可以具有默认值。 OUT 参数有过程写入。用于过程需要向调用者返回多条信息的时候。不能是具有默认值的变量,也不能是常量,必须向OUT参数传递返回值。 IN OUT 具有两者的特性,可以读取和写入。 IN参数: Create table t(n number). Create or replace procedure insert_into_t (p in number ) is begin insert into t values(p). end insert_into_t. / 这个时候并没有执行该过程,尝试执行 0select * from t. exec insert_into_t (p=>. 100). 0select * from t. 例子2 0drop table t. Create table t (n number, p varchar2(20)). Create or replace procedure insert_into_t ( p1 in number, p2 in number) is begin insert into t values(p1,’p1’). insert into t values(p2,’p2’). end insert_into_t. / 这个时候并没有执行该过程,尝试执行 0select * from t. exec insert_into_t (p1=>. 100, p2=>.200). 0select * from t. 参数传递方法: 1. 使用名称表示 exec insert_into_t (p2=>. 101, p1=>.201). 2. 使用位置表示 exec insert_into_t (102, 202). 3. 使用混合表示 适用于有默认值的情况,注意:OUT 和 IN OUT 参数不能有默认值 CREATE OR REPLACE procedure default_values( P1 varchar2, P2 varchar2 default ‘Chris’, P3 varchar2 default ‘Sean’) as Begin Dbms_output.put_line(p1). Dbms_output.put_line(p2). Dbms_output.put_line(p3). End default_values. / 只想传入1,3参数: set serveroutput on exec default_values(‘Tom’, p3=>.’Joel’). OUT 参数: 从过程向调用者返回值: 例子:使用scott.emp表,编写搜索过程,输入empno,返回ename , sal 分析: desc scott.emp 参数:一个in, 两个out 参数类型:in number, out emp.ename%type , out emp.sal%type con scott/tiger create or replace procedure emp_lookup( p_empno in number, o_ename out emp.ename%type , o_sal out emp.sal%type) as begin 0select ename, sal into o_ename, o_sal from emp where empno= p_empno. exception when NO_DATA_FOUND then o_ename := ‘null’. o_sal := -1. end. /