显示结果为: Sql代码
雇员7369的名称是:SMITH 雇员7839的名称是:KING PL/SQL 过程已成功完成。 雇员7369的名称是:SMITH 雇员7839的名称是:KING PL/SQL 过程已成功完成。
说明:函数的调用直接出现在程序的DBMS_OUTPUT.PUT_LINE语句中,作为字符串表达式的一部分。如果输入了错误的雇员编号,就会在函数的错误处理部分输出错误信息。试修改雇员编号,重新运行调用部分。
【练习1】创建一个通过部门编号返回部门名称的存储函数GET_DEPT_NAME。 【练习2】将函数的执行权限授予STUDENT账户,然后登录STUDENT账户调用。 存储过程和函数的查看
可以通过对数据字典的访问来查询存储过程或函数的有关信息,如果要查询当前用户的存储过程或函数的源代码,可以通过对USER_SOURCE数据字典视图的查询得到。USER_SOURCE的结构如下: Sql代码
DESCRIBE USER_SOURCE DESCRIBE USER_SOURCE 结果为: Sql代码
名称 是否为空? 类型
------------------------------------------------------------- ------------- ----------------------- NAME VARCHAR2(30) TYPE VARCHAR2(12) LINE NUMBER TEXT VARCHAR2(4000) 名称 是否为空? 类型
------------------------------------------------------------- ------------- ----------------------- NAME VARCHAR2(30) TYPE VARCHAR2(12) LINE NUMBER TEXT VARCHAR2(4000)
说明:里面按行存放着过程或函数的脚本,NAME是过程或函数名,TYPE 代表类型(PROCEDURE或FUNCTION),LINE是行号,TEXT 为脚本。
【训练1】 查询过程EMP_COUNT的脚本。 在SQL*Plus中输入并执行如下查询: Sql代码
select TEXT from user_source WHERE NAME='EMP_COUNT'; select TEXT from user_source WHERE NAME='EMP_COUNT'; 结果为: Sql代码 TEXT
-------------------------------------------------------------------------------- PROCEDURE EMP_COUNT(P_TOTAL OUT NUMBER) AS BEGIN
SELECT COUNT(*) INTO P_TOTAL from EMP; END; TEXT
-------------------------------------------------------------------------------- PROCEDURE EMP_COUNT(P_TOTAL OUT NUMBER) AS BEGIN
SELECT COUNT(*) INTO P_TOTAL from EMP; END;
【训练2】 查询过程GET_EMP_NAME的参数。 在SQL*Plus中输入并执行如下查询: Sql代码
DESCRIBE GET_EMP_NAME DESCRIBE GET_EMP_NAME 结果为: Sql代码
FUNCTION GET_EMP_NAME RETURNS VARCHAR2 参数名称 类型 输入/输出默认值?
----------------------------------------- ----------------------------------- ----------------- ------------- P_EMPNO NUMBER(4) IN DEFAULT FUNCTION GET_EMP_NAME RETURNS VARCHAR2 参数名称 类型 输入/输出默认值?
----------------------------------------- ----------------------------------- ----------------- ------------- P_EMPNO NUMBER(4) IN DEFAULT
【训练3】 在发生编译错误时,显示错误。 Sql代码
SHOW ERRORS SHOW ERRORS
以下是一段编译错误显示: Sql代码
LINE/COL ERROR
------------- ----------------------------------------------------------------- 4/2 PL/SQL: SQL Statement ignored 4/36 PLS-00201: 必须说明标识符 'EMPP' LINE/COL ERROR
------------- ----------------------------------------------------------------- 4/2 PL/SQL: SQL Statement ignored 4/36 PLS-00201: 必须说明标识符 'EMPP'
说明:查询一个存储过程或函数是否是有效状态(即编译成功),可以使用数据字典USER_OBJECTS的STATUS列。
【训练4】 查询EMP_LIST存储过程是否可用: Sql代码
SELECT STATUS from USER_OBJECTS WHERE OBJECT_NAME='EMP_LIST'; SELECT STATUS from USER_OBJECTS WHERE OBJECT_NAME='EMP_LIST'; 结果为: Sql代码 STATUS ------------ VALID STATUS ------------ VALID
说明:VALID表示该存储过程有效(即通过编译),INVALID表示存储过程无效或需要重新编译。当Oracle调用一个无效的存储过程或函数时,首先试图对其进行编译,如果编译成功则将状态置成VALID并执行,否则给出错误信息。
当一个存储过程编译成功,状态变为VALID,会不会在某些情况下变成INVALID。结论是完全可能的。比如一个存储过程中包含对表的查询,如果表被修改或删除,存储过程就会变成无效INVALID。所以要注意存储过程和函数对其他对象的依赖关系。
如果要检查存储过程或函数的依赖性,可以通过查询数据字典USER_DENPENDENCIES来确定,该表结构如下:
Sql代码
DESCRIBE USER_DEPENDENCIES; DESCRIBE USER_DEPENDENCIES; 结果: Sql代码
名称 是否为空? 类型
-------------------------------------------------------------- ------------- ---------------------------- NAME NOT NULL VARCHAR2(30) TYPE VARCHAR2(12)
REFERENCED_OWNER VARCHAR2(30) REFERENCED_NAME VARCHAR2(64) REFERENCED_TYPE VARCHAR2(12) REFERENCED_LINK_NAME VARCHAR2(128) SCHEMAID NUMBER
DEPENDENCY_TYPE VARCHAR2(4) 名称 是否为空? 类型
-------------------------------------------------------------- ------------- ---------------------------- NAME NOT NULL VARCHAR2(30) TYPE VARCHAR2(12)
REFERENCED_OWNER VARCHAR2(30) REFERENCED_NAME VARCHAR2(64) REFERENCED_TYPE VARCHAR2(12)
REFERENCED_LINK_NAME VARCHAR2(128) SCHEMAID NUMBER
DEPENDENCY_TYPE VARCHAR2(4)
说明:NAME为实体名,TYPE为实体类型,REFERENCED_OWNER为涉及到的实体拥有者账户,REFERENCED_NAME为涉及到的实体名,REFERENCED_TYPE 为涉及到的实体类型。
【训练5】 查询EMP_LIST存储过程的依赖性。 Sql代码
SELECT REFERENCED_NAME,REFERENCED_TYPE from USER_DEPENDENCIES WHERE NAME='EMP_LIST'; SELECT 执行结果: Sql代码
REFERENCED_NAME,REFERENCED_TYPE
from
USER_DEPENDENCIES WHERE NAME='EMP_LIST';
REFERENCED_NAME REFERENCED_TYPE
------------------------------------------------------------------------------------------ ----------------------------
STANDARD PACKAGE
SYS_STUB_FOR_PURITY_ANALYSIS PACKAGE DBMS_OUTPUT PACKAGE DBMS_OUTPUT SYNONYM DBMS_OUTPUT NON-EXISTENT EMP TABLE
EMP_COUNT PROCEDURE REFERENCED_NAME REFERENCED_TYPE
------------------------------------------------------------------------------------------ ---------------------------- STANDARD PACKAGE
SYS_STUB_FOR_PURITY_ANALYSIS PACKAGE DBMS_OUTPUT PACKAGE DBMS_OUTPUT SYNONYM DBMS_OUTPUT NON-EXISTENT EMP TABLE
EMP_COUNT PROCEDURE
说明:可以看出存储过程EMP_LIST依赖一些系统包、EMP表和EMP_COUNT存储过程。如果删除了EMP表或EMP_COUNT存储过程,EMP_LIST将变成无效。
还 有一种情况需要我们注意:如果一个用户A被授予执行属于用户B的一个存储过程的权限,在用户B的存储过程中,访问到用户C的表,用户B被授予访问用户C的 表的权限,但用户A没有被授予访问用户C表的权限,那么用户A调用用户B的存储过程是失败的还是成功的呢?答案是成功的。如果读者有兴趣,不妨进行一下实 际测试。 包
包的概念和组成
包是用来存储相关程序结构的对象,它存储于数据字典中。包由两个分离的部分组成:包头(PACKAGE)和包体(PACKAGE BODY)。包头是包的说明部分,是对外的操作接口,对应用是可见的;包体是包的代码和实现部分,对应用来说是不可见的黑盒。 包中可以包含的程序结构如下所示。 Sql代码
过程(PROCUDURE) 带参数的命名的程序模块
函数(FUNCTION) 带参数、具有返回值的命名的程序模块 变量(VARIABLE) 存储变化的量的存储单元 常量(CONSTANT) 存储不变的量的存储单元