开篇
当在PL/SQL块中执行查询语句(SELECT)和数据操纵语句(DML)时,Oracle会为其在内存中分配上下文区(Context Area),即缓冲区,游标是指向上下文区的指针。对于数据操纵语句和单行SELECT INTO语句,Oracle会为他们分配隐含游标。
显示游标
PL/SQL包含隐含游标和显示游标两种游标类型,其中隐含游标用于处理SELECT INTO和DML语句,显示游标则专门用于处理SELECT语句返回的多行数据。
--1、定义显示游标
CURSOR c_rows IS
SELECT col1, col2 FROM t;
v_col1 t.col1%type;
v_col2 t.col2%type;
begin
--2、打开游标
OPEN c_rows;
LOOP
--3、提取数据
FETCH c_rows INTO v_col1, v_col2;
EXIT WHEN c_rows%NOTFOUND;
dbms_output.put_line(v_col1 || ',' || v_col2);
END LOOP;
--4、关闭游标
CLOSE c_rows;
end TEST_CURSOR;
从上例可以总结出,使用显示游标包括定义游标、打开游标、提取数据和关闭游标四个阶段。
(1)定义游标
在使用显示游标之前,必须首先在定义部分定义游标。定义游标用于指定游标所对应的SELECT语句,语法如下:
cursor_name用于指定游标名称;select_statement用于指定游标所对应的SELECT语句。
(2)打开游标
当打开游标时,Oracle会执行游标所对应的SELECT语句,并将SELECT语句的结果暂时存放到结果集中。语法如下:
该游标名必须是在定义部分已经定义的游标。
(3)提取数据
在打开游标之后,SELECT语句的结果被临时存放到游标结果集中。为了处理结果集中的数据,需要使用FETCH语句提取游标数据。语法如下:
v1, v2用于接收游标数据的变量。
(4)关闭游标
在提取并处理了结果集的所有数据之后,就可以关闭游标并释放其结果集了,语法如下:
本文链接
大多数阅读过Oracle相关内容的用户会听说过它的三个核心效力,即:
- 可扩充性——Oracle系统有能力承担增长的工作负荷,并且相应地扩充它的系统资源利用情况。这意味着给定的系统既可以服务于10个用户,也可以有效地服务于每个用户同时运行5个会话的10000个用户。
- 可行性——无论出现操作系统崩溃、电源断电还是系统故障,都可以对Oracle进行配置,以保证在检索用户数据和进行事务处理的时候不受任何影响。
- 可管理性——数据库管理员可以微调Oracle使用内在的方式、Oracle向磁盘写入数据的频率,以及数据库为连接到数据库的用户分配操作系统进行的方式。
本章我们将要讨论:
- 为什么理解体系结构很重要
- 使用Oracle Net Services在用户进程和数据库之间进行连接
- 服务器进程
- 文件
- 内在区域
- 后台进程
5.1 为什么必须理解体系结构
许多操作系统的细节都可以对应用开发者和数据库管理员进行抽象。应用只编写一次,就可以部署于几乎任何服务器操作系统上。例如,用户可以基于运行于用户开发服务器上的数据库构建用户应用,开发服务器为具有双处理器的Windows 2000服务器。当应用开发调试完毕之后,用户可以不作任何代码修改,只要花费一定的时间(依赖于应用的规模和数据)就可以将应用配置到Solaris硬件上运行的4个处理口碑 Sun Solaris计算机上。在一段日子以后,用户的IT部门可能会决定将公司所有的硬件设备都移植到Linux。无论这种硬件改变的原因如何,Oracle都可以在这些平台上以一种相似的方式运行。用户只需从原始数据库中导出所有模式,并将它们导入到目标数据库中。而在客户计算机上不必进行修改,除非用户需要改变网络配置,指向新的服务器。如果已经在数据库中构建了用户应用,那么服务器应用根本不需要进行改变。
5.2 进行连接
在这一节中,我们将要讨论Oracle体系结构中协同工作的三个领域,它们可以为我们提供连接数据库实例的能力。它们是:
- 用户进程
- Oracle监听器
- Oracle网络客户
5.2.1 用户进程
可以将用户进程(User Process)看作是一些试图连接数据库的软件(例如客户工具)。用户进程会使用Oracle Net Services(Oracle网络服务)与数据库进行通信,网络服务是一组通过网络连接协议提供网络连接的组件。Oracle Net对应用开发者和数据库管理员屏蔽了不同硬件平台上配置不同网络的复杂性。Oracle不用编辑Windows 2000服务器上的注册表,或者Linux服务器上/etc中的配置文件,而是使用一些简单的配置文件(在Oracle安装区域中的一个位置)就可以管理OracleNet。Oracle提供了(并且鼓励使用)Oracle Net Manager(Oracle网络管理器)以及Oracle Net Configuration Assistant(Oracle 网络配置助理)这样的工具来设置用户的Oracle Net Services配置。
由于在所有的平台上都使用了相同的文件,所以在用户最熟悉的操作系统上了解它们的语法,然后使用这些知识配置任何服务器上的文件就很容易。
5.2.2 Oracle监听器
监听器(listener)是一个通常运行于Oracle数据库服务器上的进程,它负责“监听”来自于客户应用的连接请求。客户负责在初始化连接请求中向监听器发送服务名称(service name)。这个服务名称是一个标识符,它可以唯一标识客户试图连接的数据库实例。
监听器可以接受请求,判断请求是否合法,然后将连接路由到适当的服务处理器(service handler)。服务处理器是一些客户请求试图连接的进程。在数据库服务的例子中,两种类型的服务处理器分别是专用服务器进程或者共享服务器进程。当把连接路由到合适的服务处理器之后,监听器就完成了它的职责,就可以等候另外的连接请求。
Oracle 8i和Oracle 9i数据库可以使用监听器动态配置它们的服务。动态注册(也称为服务注册)可以通过称为进程监控器的Oracle后台进程或者PMON来完成。动态注册意味着数据库可以告诉监听器(与数据库处于相同服务器的本地监听器或者远程监听器)服务器上可以使用的服务。
即使没有在用户监听器配置文件中明确设置静态监听配置,同时用户数据库无法使用动态注册,监听器也会使用安装它的时候的默认值。标准的监听器会使用如下假定:
- 网络协议:TCP/IP
- 主机名称:运行监听器的主机
- 端口:1521
监听器配置
如果用户想要手工配置用户监听器,那么就可以在listener.ora文件找到配置信息,它通常位于Unix上的$ORACLE_HOME/network/admin目录中,或者Windows上的%ORACLE_HOME%\network\admin目录中。在两个平台上,就可以建立名为TNS_ADMIN的环境变量,指向Oracle网络服务文件所处的目录。这可以方便管理员将它们的配置文件放置到默认位置以外的某个地方。
listener.ora文件(在Linux服务器上)的示例如下所示:
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = slaphappy.us.oracle.com)(PORT = 1521))
)
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = slqpdb.us.oracle.com)
(ORACLE_HOME = /u01/app/oracle/Oracle 9i)
(SID_NAME =slapdb)
)
)
SAVE_CONFIG_ON_STOP_LISTENER=ON
LOG_FILE_LISTENER=lsnr.log
LOG_DIRECTORY_LISTENER=/u01/app/oracle/Oracle 9i/network/log
TRACE_FILE_LISTENER=lsnr
TRACE_DIRECTORY_LISTENER=/u01/app/oracle/Oracle 9i/network/log
TRACE_LEVEL_LISTENER=0FF
第一个表项LISTENER是一个命名监听器,它会使用TCP/IP协议监听slaphappy.us.oracle.com上的端口1521.LISTENER是用户安装数据库时Oracle监听器的默认名称,但是可以使用不同的名称建立多个监听器,监听多个端口。
SID_LIST_LISTENER标识了正在连接LISTENER的客户可以使用的服务。SID部分代表系统标识符(System Identifier)。在以上的配置中,SLAPDB是全局数据库库的名称,US.ORACLE.COM是在安装期间赋给数据库的全局数据库域。SLAPDB是在安装期间指定给数据库的实例名称,ORACLE_HOME是安装Oracle数据库的目录。
当监听器运行的时候,它就可以使用Oracle提供的名为lsnrct1的实用工具(实用工具的名称可能会在版本之间发生变化)修改它的配置。这是一个命令行模式的应用,它可以提供大量有帮助的操作,例如STOP、START、RELOAD、STATUS、SHOW(参数)、SET(参数)等。
在以上的监听器配置文件中,SAVE_CONFIG_ON_STOP_LISTENER设置可以告诉Oracle网络服务是否将监听器设置的修改结果写入listener.ora文件。
LOG_FILE_LISTENER和LOG_DIRECTORY_LISTENER标识
很多年来,Oracle教师、管理员、程序员、以及用户为了学习、测试或调整他们的数据库,都一直在使用这个值得依赖的SCOTT模式进行着简单地查询、更新、以及删除操作。这些模式就是我们所说的示例模式。示例模式是表、视图、索引这样的数据库对象的集合,并且随之预先供了代表小规模或者中等规模公司的数据。
随着最新版本的Oracle数据库Oracle 9i的出现,又引进了全新的一组示例模式,它们的目标是扩展SCOTT模式向用户提供的功能。所有这些模式一起形成了相同的虚拟公司的一部分,它们各自都有自己的业务侧重点。例如,人力资源部、订单输入部门以及发货部门都有分离的模式。
注意:
当前hr已经锁定了(即lock)。需要执行以下脚本:
SQL> connect system/zyf;已连接。
SQL> alter user hr account unlock;
用户已更改。
SQL> alter user hr identified by hr;
用户已更改。
SQL> connect hr/hr;
已连接。
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
COUNTRIES
DEPARTMENTS
EMPLOYEES
JOBS
JOB_HISTORY
LOCATIONS
REGIONS
已选择7行。
4.1 SCOTT模式
所提供的SCOTT模式可以提供一些示例表以及数据,来展示数据库的一些特性。它是一个相当简单的模式,如图4-1数据结构图所示(通过PowerDesign逆向工程转换为数据库模型)。
图4-1 SCOTT模式数据结构图
为什么要将这个模式命名为SCOTT呢?SCOTT/TIGER是Oracle版本1、2和3时代的Oracle数据库的最初用户名/密码组合。SCOTT是指Oracle公司的元老程序员Bruce Scott。当然,TIGER是Bruce养的猫的名字。
SCOTT模式中所展示的数据库特性通常被认为是大多数关系数据库产品中的主要特性。如果想要真实地展示Oracle数据库的功能,就要深化这些示例!
4.2 Oracle 9i示例模式
Oracle技术可以应用于各种不同的环境中。技术解决方案的两个应用极端情况是,高速在线事务处理和数据库仓库。尽管用户可以使用一个模式,展示怎样在相同的表中完成在线事务处理和数据仓库。但是用户决不可能采用这种方式实现实用的解决方案。我们在如今的业界中经常可以发现,为了解决现实世界中的不同计算需求,通常在单独的数据库实例中会存在不同的模式,或者在网络上会有大量分布式数据库。新的Oracle 9i示例模式模型极好地对这个场景建模。
Oracle 9i示例模式试图模型化一个现实世界中具有一系列典型业务部门的销售组织。这些不同的部门具有不同的信息技术需要,每一个示例模式都使用了不同的Oracle技术来解决它们各自的问题。另外,每个模式设计方案都针对特定的技术用户。这些模式如下:
- HR——人力资源。
- OE——订单输入。
- PM——产品媒体。产品媒体在数据库中存储了公司系列产品的相关多媒体内容,可以用于在Web上发布以及打印。PM利用了Oracle Intermedia,它专门设计用于处理发布音频、视频以及可视数据的多媒体领域。另外,PM也频繁地使用了LOB列类型。
- QS——队列运送。运送部门负责记录公司向客户进行的产品运送情况,并且使用6个模式来完成这项工作。QS、QS_ES、QS_WS、QS_OS、QS_CB和QS_CS构成了队列运送模式的集合。
- SH——销售历史。
4.2.1 深入讨论各个模式
1. 人力资源
人力资源模式,或者HR模式,负责管理部门、雇员、工作以及薪金信息。图4-2展示了HR模式的详细数据结构图示。
2. 订单输入
订单输入(Order Entry)模式,或者OE模式,可以用来管理公司从事商务活动的各个渠道中的客户、销售订单以及产品库存。
图4-3详细描绘了OE模式的数据结构。就如我们早先了解的,与人力资源模式相比,订单输入模式更为复杂。
图4-3 OE模式数据结构
OE模式会记录产品库存。我们将会存储任意指定仓库中指定产品的数量。在公司中会有多个仓库,所以要使用地点标识符指出其地理区域。在WAREHOUSES表中还有一个Oracle Spatial列,它为我们提供了使用Oracle Spatial空间技术的钥匙。
Oracle Spatial是在数据库中支持位置数据和地理数据的技术。
在OE模式中,需要顺便提供提及两个数据库对象模型:
- CUST_ADDRESS_TYP。这是一个在CUSTOMERS表中使用的对象类型。它包含了许多与客户地址有关的属性。
名称 是否为空? 类型
----------------------------------------- --------
STREET_ADDRESS VARCHAR2(40)
POSTAL_CODE VARCHAR2(10)
CITY VARCHAR2(30)
STATE_PROVINCE VARCHAR2(10)
COUNTRY_ID CHAR(2)
- PHONE_LIST_TYP。这是一个VARCHAR2(25)的VARRAY。这个VARRAY在CUSTOMERS表中作为单独的列存储,可以用于存储最多5个电话号码。
phone_list_typ VARRAY(5) OF VARCHAR2(25)
OE模式是一个很好的示例,它展示了正规的供应组织或者计算机零售商店可以使用什么方式去管理它们完整订单处理过程。通过使用订单输入表中的数据,销售组织就可以向潜在的客户提供精确的产品信息,接受销售订单,量化订单收入,存储客户信息,为不同地理位置订购产品的客户提供精确的库存信息,以及其它服务。
3. 产品媒体
产品媒体(Product Media)模式,或者PM模式,用于管理描述公司产品的多媒体数据。视频、音频和图像这样的在线媒体都可以随输出的媒体数据类型存储在数据库中。这是我们要专门研究的模式之一,它着重于多媒体内容,以及Oracle Intermedia所提供的功能。
注意:
Oracle Intermedia是Oracle数据库支持多媒体内容类型的组件。
除了Intermedia数据存储以外,PM模式还特别依赖LOB列类型的使用来存储数据。
产品媒体模式是Oracle 9i使用名为Oracle Intermedia的Oracle技术解决现实世界商务需求的优秀示例。例如,我们虚构的公司就可以存储多媒体数据或者输出多媒体数据。因此,产品媒体模式中的示例可以完成如下工作:
- 为Oracle中利用Web发布的内容存储缩略图和完全尺寸的图像。
- 在Oracle中存储音频剪辑。
- 在Oracle中存储视频剪辑。
- 对图像类型进行处理,以便转换成与Web兼容的图像类型
利用Oracle Intermedia,一些曾经很难实现的任务就变得相对简单。图4-4表示为产品媒体模式,以及它对订单输入表PRODUCT_INFORMATION的引用。
图4-4 PM模式数据结构
PRINT_MEDIA表拥有一个对象类型(ADHEADER_TYP),以及在表的各个记录中存储的对象嵌套表(TEXTDOC_TAB)。
ORDSYS.ORD__列都是一个Intermedia对象类型。这些Intermedia对象类型不仅可以存储图像、音频、视频这样的二进制数据;还可以存储各种与多媒体类型有关的元数据。
SQL> desc ordsys.ordimage;4. 队列运送
我们的虚拟公司想要使用消息系统,以方便在线客户进行自助订货。当客户初始化订货的时候,系统就需要建立订单,向客户提供账单,并且要确保可以根据客户的位置,通过适当的地区发送订货。
QS_CS模式有一个名为ORDER_STATUS_TABLE的表,可以存储订单状态。这是在整个队列运送模式安装过程中唯一建立表(除了通过高级队列API建立的队列表以外)。我们不会展示与表有关的数据结构图,而是要讨论为队列运送模式所建立的队列系统中的消息流程。
图4-5所示流程图示中可以看到,为了提供一个清晰、直观的订货——发货——结算循环,要在部门之间怎样传递消息。
图4-5 为队列运送(QS)模式在队列系统中建立的消息流程
一切都要从图示顶部的订单输入开始。Oracle Input(订单输入)过程所生成的订单会放入New Order Queue(新订单队列)中。这个队列要Oracle Entry应用处理,然后会将订单放到Booked Orders Queue(登记订单队列)中。再将Booked Orders Queue中的订单发往适当的运送中心(East(东部)、West(西部)或者Overseas(海外)),以及客户服务部门。
在这时,运送中心就会接收要完成的订单,并且向客户发送订货,而且客户服务部门也会意