老二牛车第七章理论课子程序和程序包_第1页
老二牛车第七章理论课子程序和程序包_第2页
老二牛车第七章理论课子程序和程序包_第3页
老二牛车第七章理论课子程序和程序包_第4页
老二牛车第七章理论课子程序和程序包_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Oracle数据库应用 理论课 子程序和程序包 本章 技能 目标 创建和使用子程序 创建和使用程序包 1. 子程序 子程序是 命名的 PL/SQL 块,编译并存储在数据库中。 可以为它们指定参数,可以从任何 数据库客户端和应用程序中调用它们。命名的 PL/SQL 程序包包括存储过程和函数。程序包是存储过程和函数的集合。 与未命名或匿名 PL/SQL 块一样,子程序也有声明部分,执行部分和一个可选的异常处理部分。声明部分包含类型、游标、常量、变量、异常和嵌套子程序的声明。这些内容都是本 地的,在程序退出时会自动销毁。执行部分包含赋值语句、流程控制语句和 Oracle 的数据操作语句。异常处理部分包含异常处理 处理。 子程序的各个部分: 声明部分 可执行部分 异常处理部分 (可选 ) 子程序的分类: 过程 执行某些操作 函数 执行操作并返回值 子程序的优点 如下 : 模块化 : 通过子程序,可以将程序分解为可管理的,明确的 逻辑模块 可重用性 :子程序在创建并执行后,就可以在 任意数目的程序 中 调用 可维护性 :子程序可以 简化维护操作 ,因为如果一个子程序受到影响,则只需要修改该子程序的定义。 安全性 : 通过设置权 限,使数据 访问的唯一方式就是通过用户提供的过程和函数,这不仅可以让数据更加安全,而且还可以保证它的正确性。 1.1 过程 第 7章 子程序和程序包 - 2 - 2 过程是 执行某些操作的子程序, 它是执行 特定任务的 模块。 从根本上讲,过程就是命名的PL/SQL 块,它可以被赋予参数,存储在数据库中,然后由一个应用程序或其它 PL/SQL 程序调用。 创建过程: 用于 创建过程的语法 如下 : CREATE OR REPLACE PROCEDURE () IS|AS BEGIN EXCEPTION END ; 其中: procedure_ name 是过程的名称, parameter_ list 是参数列表, local_variable_declaration 是局部声明。 executable_ statements 是可执行语句, exception_ handlers 是异常处理程 序。 创建过程的语法的大部分都与 PL/SQL 块相似。声明部分置于关键字 IS 与 BEGIN 之间。 存储过程中的声明不使用 DECLARE关键字 .过程最后的 END关键字后可以使用可选的 .其它部分与匿名 Pl/SQL 块完全相同。 例 1 演示如何创建过程。 例 1: CREATE OR REPLACE PROCEDURE find_emp(emp_no NUMBER) AS empname VARCHAR2(20); BEGIN SELECT ename INTO empname FROM EMP WHERE empno = emp_no; DBMS_OUTPUT.PUT_LINE(雇员姓名是 | empname); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE (雇员编号未找到 ); END find_emp; / 该例创建了 find_emp 过程。该过程接受一个雇员编号参数 emp_no,然后 SELECT 语句从 EMP表中选择 empno 为 emp_no 的雇员记录,并显示雇员。如果在表中未找到此雇 员编号。 该过程显示 NO_DATA_FOUND 异常,并显示消息“ 雇员编号未找到 ”。 例 1-1: CREATE OR REPLACE PROCEDURE getDeptCount AS deptCount int; BEGIN SELECT COUNT(*) INTO deptCount FROM dept; DBMS_OUTPUT.PUT_LINE(dept 表共有 |deptCount|行记录 ); END getDeptCount; 第 7章 子程序和程序包 - 3 - 3 创建不带参数的存储过程,该过程返回 dept 表行数 。 当我们创建的存储过程没有参数时,在存储过程名字后面不能有括号 。 执行过程 在 SQL 提示符下,使用 EXECUTE 语句来执行过程。 执行过程的语法 如下 : EXECUTE procedure_name(parameters_list); 其中: procedure_ name 是过程的名称, parameter_ list 是参数列表。 要执行 find_emp 过程,请输入以下命令。 SETSERVEROUTPUT ON EXECUTE find_emp (7900); 还 使用以下代码可以执行存储过程: BEGIN getDeptCount; END; 还可以通过以下代码来简化调用: EXEC getDeptCount; CALL getDeptCount(); 注意: 并不是所有的存储过程都可以用这种方式来调用 定义无参存储过程时,存储过程名后不能加 () 在块中或是通过 EXEC 调用存储过程时可以省略 () 通过 CALL 调用无参存储过程必须加上 () 过程参数模式: 过程参数的三种模式: IN ,OUT,IN OUT 。 定义过程参数的语法如下: parameter_name IN | OUT | IN OUT datatype := | DEFAULT expression IN 用于接受调用程序的值 默认的参数模式 OUT 用于向调用程序返回值 IN OUT 用于接受调用程序的值,并向调用程序返回更新的值 在返回到调用环境之前,必须先给 OUT 或 IN OUT 参数赋值。 可以在参数列表中为 IN 参数赋予一个默认值,不能为 OUT, IN OUT 参数赋予默认值。 创建带有 IN 参数的存储过程 。 例 2: CREATE OR REPLACE PROCEDURE itemdesc(item_code IN VARCHAR2) IS v_itemdesc VARCHAR2(5); 第 7章 子程序和程序包 - 4 - 4 BEGIN SELECT itemdesc INTO v_itemdesc FROM itemfile WHERE itemcode = item_code; DBMS_OUTPUT.PUT_LINE(item_code|项目的说明为 |v_itemdesc); END; / 要执行 itemdesc 过程,请输入以下查询。 EXECUTE itemdesc (i201); / 例 2-1: CREATE OR REPLACE PROCEDURE getSalaryByEmpNo0(eNo NUMBER) -参数的数据类型不能指定长度 AS salary emp.sal%TYPE; BEGIN SELECT SAL INTO salary FROM EMP WHERE EMPNO=eNo; DBMS_OUTPUT.PUT_LINE(eNo|号员工的工资为 |salary); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE(没有找到该编号的员工 ); END; 当定义的存储过程含有参数时,参数的数据类型不能指定长度。参数还有输入和输出之分,本例中没有指定,默认情况为输入参数,也可显示的指定某个参数是输入参数,如 (eNo IN NUMBER)。 BEGIN getSalaryByEmpNo0(7788); END; / EXEC getSalaryByEmpNo0(7788); / CALL getSalaryByEmpNo0(7788); 但是如果传给一个存储过程的参数是变量时,必须 使用 BEGIN END 块,如下: DECLARE no emp.empNo%TYPE; BEGIN no:=7788; getSalaryByEmpNo(no); END; 如果某个包中含有常量,也可以通过如下的方式调用: EXEC getSalaryByEmpNo(ConstantPackage.no); 但这种方式不能再使用 CALL 调用。 创建带有 OUT 参数的存储过程 。 例 3: CREATE OR REPLACE PROCEDURE test(value1 IN VARCHAR2,value2 OUT NUMBER) IS identity NUMBER; 第 7章 子程序和程序包 - 5 - 5 BEGIN SELECT ITEMRATE INTO identity FROM itemFile WHERE itemcode = value1; IF identity 7788); -使用默认值 EXEC addEmp(mgr=7788,empNo=7779,eName=sunliu); -更改参数顺序 将过程的执行权限授予其他用户: 过程创建之后,只有创建该过程的用户才有权调用它。其它用户如果要调用该过程,需要得到过程的 EXECUTE 权限。 例 6 演示如 何将执行过程的权限授予其它用户。 例 6: SQL GRANT EXECUTE ON find_emp TO MARTIN; SQL GRANT EXECUTE ON swap TO PUBLIC; 维护过程 1、删除存储过程 DROP PROCEDURE Proc_Name; 2、查看过程状态 SELECT object_name,status FROM USER_OBJECTS WHERE object_type=PROCEDURE; 3、重新编译过程 ALTER PROCEDURE Proc_Name COMPILE; 4、查看过程代码 SELECT * FROM USER_SOURCE WHERE TYPE=PROCEDURE; 1.2 函数 函数与过程相似,也是数据库中已命名 PL/SQL 程序块。函数的主要特性是它必须返回一个值。创建函数时通过 RETURN 子句指定函数返回值的数据类型。 在函数体的任何地方用户都可以通过 RETURN expression 语句从函数返回,这里的表达式的数据类型要与 RETURN 子句指定的类型相同。 与过程类似,函数 将代码分割成模块,有助于组织代码。 定义函数 用于定义函数的语法如下: CREATE OR REPLACE FUNCTION (param1,param2) RETURN IS|AS local declarations BEGIN 第 7章 子程序和程序包 - 8 - 8 Executable Statements; RETURN result; EXCEPTION Exception handlers; END; 创建函数 例 7 演示如何创建 函数 。 例 7: CREATE OR REPLACE FUNCTION fun_hello RETURN VARCHAR2 IS BEGIN RETURN 朋友,您好!今天是 | TO_CHAR(SYSDATE, DAY); END; / 上例创建了一个简单函数 fun_hello。 与过程不同,函数不能单独执行,只能通过 SQL 语句或 PL/SQL 程序块来调用。 访问函数的两种方式: 使用 PL/SQL 块 使用 SQL 语句 要调用此函数,请输入以下语句。 SELECT fun_hello FROM DUAL; 上述语句将返回消息“朋友,您好” 。 例 8 演示一个有业务功能的函数 。 例 8: CREATE OR REPLACE FUNCTION item_price_range (price NUMBER) RETURN VARCHAR2 AS min_price NUMBER; max_price NUMBER; BEGIN SELECT MAX(ITEMRATE), MIN(ITEMRATE) INTO max_price, min_price FROM itemfile; IF price = min_price AND price job); DBMS_OUTPUT.PUT_LINE(job); END; 创建带有输入输出参数的函数 例 13: CREATE OR REPLACE FUNCTION getHiredateAndJobByEmpName(nb IN OUT VARCHAR2) RETURN DATE AS hireDate DATE; BEGIN SELECT hiredate,job INTO hireDate,nb FROM EMP WHERE eName=nb; RETURN hireDate; END; 当函数中有输出参数时,不能直接通过 SELECT 语句查看,必须在 BEGIN END 块中调用,如下: DECLARE n emp.eName%TYPE:=SCOTT; BEGIN DBMS_OUTPUT.PUT_LINE(getHiredateAndJobByEmpName(n); DBMS_OUTPUT.PUT_LINE(n); END; 第 7章 子程序和程序包 - 11 - 11 将 函数 的执行权限授予其他用户: 与过程相同,用户要调用其它用户的函数也需要得到授权,权限的名称也是 EXECUTE。 SQL GRANT EXECUTE ON fun_hello TO MARTIN; 维护函数 1、删除函数 DROP FUNCTION Fun_Name; 2、查看函数状态 SELECT object_name,status FROM USER_OBJECTS WHERE object_type=FUNCTION; 3、重新编译函数 ALTER FUNCTION Fun_Name COMPILE; 4、查看函数代码 SELECT * FROM USER_SOURCE WHERE TYPE=FUNCTION; 使用函数的限制: 从 SQL 表达式调用函数有以下限制: 从 SELECT 语句调用的任何函数均不能修改数据库表。 当远程执行或并行执行时,函数不得读取或写入程序包中的变量。 从 SELECT, VALUES 或 SET 子句调用的函数可以写入程序包变量,所有其他子句中的函数均不能写入程序包变量。 如果函数调用执行 UPDATE 的存储过程,则该函数不能在 SQL 语句中使用。 1.3 过程和函数的比较 过程和函数的比较 过 程 函 数 作为 PL/SQL 语句执行 作为表达式的一部分调用 在规格说明中不包含 RETURN 子句 必须在规格说明中包含 RETURN 子句 不返回任何值 必须返回单个值 可以包含 RETURN 语句,但是与函数不同,它不能用于返回值 必须包含至少一条 RETURN 语句 1.4 自治 事务处理 自治事务允许你离开调用的事务上下文,执行一个独立的事务,然后返回调用的事务而不 会影响到调用事务的状态。自治事务和调用事务不同,只有提交的事务才会在事务见共享。 以下的 PL/SQL 代码块可以定义为自治事务。 第 7章 子程序和程序包 - 12 - 12 存储过程和函数 定义在声明块里的本地存储过程和函数 打包的存储过程和函数 类型方法 顶层的匿名块 最简单的理解自治事务的方法是查看他们的行为。我们创建一个测试表格,然后放入 2 行数据,注意数据没有提交。 CREATE TABLE at_test ( id NUMBER NOT NULL, description VARCHAR2(50) NOT NULL ); INSERT INTO at_test (id, description) VALUES (1, Description for 1); INSERT INTO at_test (id, description) VALUES (2, Description for 2); SELECT * FROM at_test; ID DESCRIPTION - - 1 Description for 1 2 Description for 2 2 rows selected. 下一步,我们使用匿名的自治事务块插入另外 8 行数据,同时提交。 DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN FOR i IN 3 . 10 LOOP INSERT INTO at_test (id, description) VALUES (i, Description for | i); END LOOP; COMMIT; END; / PL/SQL procedure successfully completed. SELECT * FROM at_test; ID DESCRIPTION - - 1 Description for 1 2 Description for 2 3 Description for 3 4 Description for 4 5 Description for 5 6 Description for 6 7 Description for 7 8 Description for 8 第 7章 子程序和程序包 - 13 - 13 9 Description for 9 10 Description for 10 10 rows selected. 和预想的一样,我们得到了 10 行数据。如果我们执行一个回滚 (rollback)语句,我们得到了如下的结果 ROLLBACK; SELECT * FROM at_test; ID DESCRIPTION - - 3 Description for 3 4 Description for 4 5 Description for 5 6 Description for 6 7 Description for 7 8 Description for 8 9 Description for 9 10 Description for 10 8 rows selected. 被我们当前事务插入的 2 行数据被回滚了,而被自治事务插入的数据继续存在。编译描述符 PRAGMA AUTONOMOUS_TRANSACTION 使得自治块在自己的事务里运行,所以内部的提交语句不会影响调用方的事务 自治事务一般用于日常的错误日志,错误信息必须保留,无论事务是提交还是回滚。例如下面的表保存了基本的错误信息。 CREATE TABLE error_logs ( id NUMBER(10) NOT NULL, log_timestamp TIMESTAMP NOT NULL, error_message VARCHAR2(4000), CONSTRAINT error_logs_pk PRIMARY KEY (id) ); CREATE SEQUENCE error_logs_seq; 我们定义了一个自治事务的存储过程来记录错误信息 CREATE OR REPLACE PROCEDURE log_errors (p_error_message IN VARCHAR2) AS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO error_logs (id, log_timestamp, error_message) VALUES (error_logs_seq.NEXTVAL, SYSTIMESTAMP, p_error_message); COMMIT; END; / 下面的代码强制产生一个错误 ,被捕获且记录到日志 。 BEGIN 第 7章 子程序和程序包 - 14 - 14 INSERT INTO at_test (id, description) VALUES (998, Description for 998); - Force invalid insert. INSERT INTO at_test (id, description) VALUES (999, NULL); EXCEPTION WHEN OTHERS THEN log_errors (p_error_message = SQLERRM); ROLLBACK; END; / PL/SQL procedure successfully completed. SELECT * FROM at_test WHERE id = 998; no rows selected SELECT * FROM error_logs; ID LOG_TIMESTAMP - - ERROR_MESSAGE - 1 28-FEB-2006 11:10:10.107625 ORA-01400: cannot insert NULL into (TIM_HALL.AT_TEST.DESCRIPTION) 1 row selected. 由此可知, LOG_ERRORS 事务被分割为自治块。如果不是,我们可以期待在自治块插入的第一个数据被 LOG_ERRORS 存储过程的提交语句后保留。 小心你使用自治存储过程的方式。如果你胡乱使用,可能会引起死锁,同时在分析跟踪事务时引起冲突 。 自治 事务处理的特征: 与主事务处理的状态无关 提交或回滚操作不影响主事务处理 自治事务处 理的结果对其他事务是可见的 能够启动其他自主事务处理 2. 程序包 程序包是 一种数据库对象,它是 对相关过程、函数、变量、游标和异常等对象的封装 。 程序包由 程序包 规范和 程序包 主体两部分组成 。在程序包规范中,可以声明类型,变量,常量,异常,游标和子程序。 程序包主体用于实现在程序包规范中定义的游标,子程序。 第 7章 子程序和程序包 - 15 - 15 程序包的组成部分如下图所示: 2.1 程序包规范 程序包规范包含一些应用程序可见的公共对象和类型,是与应用程序的接口。规范包含应用程序所需的程序包资源。如果程序包规范只声明类型,常量,变量和异常,则不需要有程序包 主体,因为使用类型,常量,变量和异常所需的所有信息均已在规范中指定。只有子程序和游标才具有底层实现或定义,因此他们必须有程序包主体。 创建包规范的语法 如下 : CREATE OR REPLACE PACKAGE package_name IS|AS Public type and item declarations Subprogram specifications END package_name; 其中: package_name 是包的名称。 Public type and item declarations 是声明类型、常量、变量、异常和游标等。 Subprogram specifications 声明 PL/SQL 子程序。 在程序包规范中声明的项也可以在程序包之外使用, 这样的项称为“公用对象” 例 14 演示如何创建程序包规范 例 14: CREATE OR REPLACE PACKAGE pack_me IS PROCEDURE order_proc (orno VARCHAR2); FUNCTION order_fun(ornos VARCHAR2) RETURN VARCHAR2; END pack_me; / 该例中创建了 pack_me 包,在此程序包中,声明了子程序 order_proc 和 order_fun,这些子程序的实现定义在程序包主体中给出。 2.2 程序包主体 第 7章 子程序和程序包 - 16 - 16 程序包主体包含在程序包规范中声明的每个游标和子程序的具体实现。私有声明也可以包含在程序包主体中。 程序包主体的初始化部分是可选的,它可以用于初始化程序包中的变量。程序包的初始化部分既不能调用程序包,也不能将参数传递给程序包。 而且,程序包的初始化部分仅运行一次。 以下是创建程序包主体的语法: CREATE OR REPLACE PACKAGE BODY package_name IS|AS Public type and item declarations Subprogram bodies BEGIN Initialization_statements END package_name; 其中: package_name 是包的名称。 Public type and item declarations 声明变量,常量,游标,异常或类型 。 Subprogram bodies 定义公共和私有 PL/SQL 子程序。 例 15 演示如何创建 pack_me 包的主体。 例 15: CREATE OR REPLACE PACKAGE BODY pack_me AS PROCEDURE order_proc (orno VARCHAR2) IS stat CHAR(1); BEGIN SELECT ostatus INTO stat FROM order_master WHERE orderno = orno; IF stat = p THEN DBMS_OUTPUT.PUT_LINE(暂挂的订单 ); ELSE DBMS_OUTPUT.PUT_LINE(已完成的订单 ); END IF; END order_proc; FUNCTION order_fun(ornos VARCHAR2) RETURN VARCHAR2 IS icode VARCHAR2(5); ocode VARCHAR2(5); qtyord NUMBER; qtydeld NUMBER; BEGIN SELECT qty_ord, qty_deld, itemcode, orderno INTO qtyord, qtydeld, icode, ocode FROM order_detail WHERE orderno = ornos; IF qtyord qtydeld THEN RETURN ocode; ELSE RETURN icode; END IF; END order_fun; END pack_me; 第 7章 子程序和程序包 - 17 - 17 / 提示 : 如果创建包规范或主体时出现编译错误,请输入 SHOW ERRORS 命令查看详细的错误报告。 要引用在程序包规范中声明的类型,对象和子程序,请使用以下语法: package_name.type_name; package_name.object_name; package_name.subprogram_name; 也可以从数据库触发器,匿名的 PL/SQL 块,存储子程序和 Oracle 工具中( SQL*Plus)引用程序报内容。存储子程序可以调用程序包的子程序。 要执行 packe_me 包中的 order_proc 过程,请输入以下命令。 EXECUTE pack_me.order_proc(o002); 上述语句的输出结果如下所示: 为了执行在程序包中定义的函数,可以使用如下代码快: DECLARE msg VARCHAR2(10); BEGIN msg := pack_me.order_fun(o002); DBMS_OUTPUT.PUT_LINE(值是 | msg); END; / 2.3 程序包的优点: 程序包将相关的功能在逻辑上组织在一起,包 比 单独 的 过程具有更大的优 势。包 的 优点包括: 模块化 使用程序包,可以封装相关的类型,对象和子程序,每个程序包均将帮助我们以更好 的方式理解应用程序中涉及的概念。 更轻松的应用程序设计 要设计应用程序,必须首先在程序包规范中指定对象,类型或子程序。编译完规格说明之后,可以编译引用程序包的存储 子程序。因此,在准备 好应用程序的规格说明之前,不需要完整定义程序包主体。也就是说,可以在没有主体的情况下编写程序包规范的代码并进行编译。 信息隐藏 前面我们介绍了私有对象和公有对象。这些对象还可以用于保护程序包的完整性。假如一个程序包包含 4 个子程序 ( 3 个公有子程序和 1 个私有子程序),程序 包 隐藏私有 子 程序的定义,所以在其定义改变时,只有该程序包(而不是应用程序)受到影响。这样,实现的细节对其它用户不可见,因此保护了程序包的完整性。 新增功能 允许用户在同一个包中创建多个同名的过程,过程参数的数量或数据类型可以不同。允许创建可在包 的 所有过程和函数中使用的全局变量和游标。 第 7章 子程序和程序包 - 18 - 18 性能更佳 首次调用打包 的 子程序时,整个程序包均加载到内存中,因此,后续调用不需要磁盘 I/O。此外,如果更改已打包函数的定义,则 Oracle 不需要重新编译调用子程序 ,因为它们不依赖于子程 序的主体。 2.4 私有项与公有项 可以从其它程序和 PL/SQL 块引用包 的 公有元素。这些公有元素在规范中定义。私有元素是在程序包主体中定义的,并不出现在规范中。私有元素不能在程序包之外引用。 程序包中的任何其它元素均可以使用私有元素。 如果必须使私有元素变为公用的,则可以将该项添加到程序包规范中,然后重新编译该规范,操作完成后,该项在程序包之外将是可见的。 对于程序包元素的引用,请使用点分表示法。先后顺序为:程序包名称,点,元素名称。同一程序包不需要使用点分表示法。 在上面有关程序包规范和程序包主体的创建的例子 中。在规范的例子中,没有声明变量和游标,因此没有可以由其他程序包引用的公用变量或游标。但是,在程序包主体的例子中,过程order_proc 中定义了一个变量 stat,这个变量被认为是私有变量,此变量只能在过程内访问。 2.5 程序包中的游标 在程序包中可以定义和使用游标, 游标的定义分为游标规范和游标主体两部分 。在更改游标主体时,无需改变游标规范。此外, 在包规范中声明游标规范时必须使用 RETURN 子句指定游标的返回类型 。 RETURN 子句指示从游标获取并返回的数据元素。实际上,这些数据元素由该游标的 SELECT语句确定。但是, SELECT 语句仅出现在主体中,而不出现在规范中。游标规范必须包含程序使用游标所需的所有信息。因此需要返回数据类型。 RETURN 子句指定的数据类型可以是: 用 %ROWTYPE 属性引用表定义的记录类型 程序员定义的记录类型 例 16 演示如何在程序包中声明游标和使用游标。 例 16: CREATE OR REPLACE PACKAGE cur_pack IS CURSOR ord_cur(vcode VARCHAR2) RETURN order_master%ROWTYPE; PROCEDURE ord_pro(vcode VARCHAR2); END cur_pack; / 例 16 在 cur_pack 包中为 order_master 表创建和定义 ord_cur 游标,还创建了 ord_pro 过程。 请输入以下代码创建 cur_pack 包的主体 CREATE OR REPLACE PACKAGE BODY cur_pack AS CURSOR ord_cur(vcode VARCHAR2) RETURN order_master%ROWTYPE IS 第 7章 子程序和程序包 - 19 - 19 SELECT * FROM order_master WHERE VENCODE=vcode; PROCEDURE ord_pro(vcode VARCHAR2) IS or_rec order_master%ROWTYPE; BEGIN OPEN ord_cur(vcode); LOOP FETCH ord_cur INTO or_rec; EXIT WHEN ord_cur%NOTFOUND; DBMS_OUTPUT.PUT_LIne(返回的值为 | or_rec.orderno); END LOOP; END ord_pro; END cur_pack; / 要执行 ord_pro 过程,请输入以下命令 。 EXEC cur_pack.ord_pro(V001); 以上代码用供应商编号 v001 打开 cur_pack 包中的 ord_pro 过程。 输出结果如下: 3. 有关子程序和程序包的信息 子程序和程序包是数据库中存储的对象, Oracle 会在数据字典中存储所有对象的信息。通过查询 USER_OBJECTS 数据字典视图,可以获取有关在会话中创建的子程序和程序包的信息。 例 17 的代码 可以查询有关过程,函数和程序包的信息。 例 17: COLUMN OBJECT_NAME FORMAT A18 SELECT object_name, object_type FROM USER_OBJECTS WHERE object_type IN (PROCEDURE, FUNCTION, PACKAGE, PACKAGE BODY); 输出结果如下: OBJECT_NAME OBJECT_TYPE - - FIND_EMP PROCEDURE GETDEPTCOUNT PROCEDURE ITEMDESC PROCEDURE TEST PROCEDURE GETSALARYBYEMPNO PROCEDURE 第 7章 子程序和程序包 - 20 - 20 SWAP PROCEDURE GETSALARYBYEMPNO1 PROCEDURE ADDEMP PROCEDURE FUN_HELLO FUNCTION ITEM_PRICE_RANGE FUNCTION CURRENTTIME FUNCTION GETEMPNAMEBYEMPNO FUNCTION GETEMPNAMEANDJOBBY FUNCTION EMPNO GETSALARYBYEMPNO0 PROCEDURE GETHIREDATEANDJOBB FUNCTION YEMPNAME LOG_ERRORS PROCEDURE PACK_ME PACKAGE PACK_ME PACKAGE BODY CUR_PACK PACKAGE CUR_PACK PACKAGE BODY 通过查询 USER_SOURCE 数据字典视图,可以获取存储子过程的文本。该视图的结构如下所示: 例 18: DESC USER_SOURCE 输出结果如下: Name Type Nullable Default Comments - - - - - NAME VARCHAR2(30) Y Name of the object TYPE VARCHAR2(12) Y Type of the object: CTION, PACKAGE, PACKAGE BODY or JAVA SOURCE LINE NUMBER Y Line number of this line of source TEXT VARCHAR

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论