61阅读

易经入门学习教程-经典MPLS学习教程

发布时间:2017-09-28 所属栏目:编程学习入门

一 : 经典MPLS学习教程

目 录

目 录

第1章 MPLS简介..................................................................................................................1-1

1.1 MPLS概述......................................................................................................................1-1

1.1.1 MPLS体系结构简介..............................................................................................1-1

1.1.2 MPLS基本概念.....................................................................................................1-2

1.1.3 MPLS网络结构.....................................................................................................1-4

1.1.4 MPLS与路由协议.................................................................................................1-5

1.2 MPLS的应用...................................................................................................................1-6

i

mpls 经典MPLS学习教程

Quidway ME60 多业务控制网关 MPLS配置指南

第1章 MPLS简介

第1章 MPLS简介

多协议标签交换MPLS(Multiprotocol Label Switching)是一种结合了三层路由和二层交换优点的技术。(www.61k.com]下表列出了本章所包含的内容。 如果您需要……

了解MPLS的基本概念、组网及体系结构

了解MPLS的应用前景 请阅读…… MPLS概述 MPLS的应用

1.1 MPLS概述

本节介绍MPLS的相关术语,具体包括:

z

z

z

z MPLS体系结构简介 MPLS基本概念 MPLS网络结构 MPLS与路由协议

1.1.1 MPLS体系结构简介

MPLS起源于IPv4(Internet Protocol version 4),最初是为了提高转发速度而提出的。MPLS的核心技术可扩展到多种网络协议,包括IPv6(Internet Protocol version 6)、IPX(Internet Packet Exchange)、Appletalk、DECnet、CLNP(Connectionless Network Protocol)等。

在MPLS的体系结构中:

z 控制平面(Control Plane):无连接,利用现有IP网络实现。MPLS通过IP

网络强大灵活的路由功能,满足各种新应用对网络的要求;

z 转发平面(Forwarding Plane或者Data Plane):面向连接,可以使用ATM、

帧中继等二层网络。MPLS使用短而定长的标签(label)封装分组实现快速转发。

ME60支持在IPv4和IPv6上使用MPLS。

1-1

mpls 经典MPLS学习教程

Quidway ME60 多业务控制网关 MPLS配置指南

第1章 MPLS简介

1.1.2 MPLS基本概念

1. 转发等价类

MPLS作为一种分类转发技术,将具有相同转发处理方式的分组归为一类,称为转发等价类FEC(Forwarding Equivalence Class)。[www.61k.com)相同转发等价类的分组在MPLS网络中将获得完全相同的处理。

转发等价类的划分方式非常灵活,可以是源地址、目的地址、源端口、目的端口、协议类型、VPN等的任意组合。例如,在传统的采用最长匹配算法的IP转发中,到同一个目的地址的所有报文就是一个转发等价类。

2. 标签

标签是一个长度固定、只具有本地意义的短标识符,用于唯一标识一个分组所属的转发等价类FEC。在某些情况下,例如要进行负载分担,对应一个FEC可能会有多个标签,但是一个标签只能代表一个FEC。

标签由报文的头部所携带,不包含拓扑信息,只具有局部意义。标签的长度为4个字节,封装结构如图1-1所示。

mpls 经典MPLS学习教程

图1-1 标签的封装结构

标签中的域说明如表1-1所示。

表1-1 标签中的域说明 域 长度bit(s) 说明

标签值字段,用于转发的指针。

保留,用于试验,现在通常用做CoS(Class of Service)。

MPLS支持标签的分层结构,即多重标签。值为1时表明为最底层标

签。

与IP分组中的TTL(Time To Live)意义相同。

标签与ATM的VPI/VCI以及Frame Relay的DLCI类似,是一种连接标识符。如果链路层协议:

z 具有标签域,如ATM的VPI/VCI或Frame Relay的DLCI,则标签封装在这

些域中;

z 不具有标签域,则标签封装在链路层和IP层之间的一个垫层中。

这样,标签能够被任意的链路层所支持。标签在分组中的封装位置如图1-2所示。

1-2

mpls 经典MPLS学习教程

Quidway ME60 多业务控制网关 MPLS配置指南

第1章 MPLS简介

ATM packet in frame mode

mpls 经典MPLS学习教程

mpls 经典MPLS学习教程

ATM packet in cell mode

mpls 经典MPLS学习教程

Frame mode:帧模式 Cell mode:信元模式

图1-2 标签在分组中的封装位置

3. 标签交换路由器

标签交换路由器LSR(Label Switching Router)是MPLS网络中的基本元素,所有LSR都支持MPLS协议。(www.61k.com)

LSR由两部分组成:控制单元和转发单元。控制单元负责标签的分配、路由的选择、标签转发表的建立、标签交换路径的建立、拆除等工作;转发单元则依据标签转发表对收到的分组进行转发。

4. 标签发布协议

标签发布协议是MPLS的控制协议,它相当于传统网络中的信令协议,负责FEC的分类、标签的分配以及LSP的建立和维护等一系列操作。

MPLS可以使用多种标签发布协议。包括专为标签发布而制定的协议,例如:LDP(Label Distribution Protocol)、CR-LDP(Constraint-Routing Label Distribution Protocol);也包括现有协议扩展后支持标签发布的,例如:BGP(Border Gateway Protocol)、RSVP(Resource Reservation Protocol)。

61阅读请您转载分享:

ME60支持上述标签发布协议,并支持手工配置标签。

5. 标签交换路径

一个转发等价类在MPLS网络中经过的路径称为标签交换路径LSP(Label Switched Path)。

LSP在功能上与ATM和Frame Relay的虚电路相同,是从入口到出口的一个单向路径。LSP中的每个节点由LSR组成。

标签交换路径LSP分为静态LSP和动态LSP两种。静态LSP由管理员手工配置,动态LSP则利用路由协议和标签发布协议动态产生。

1-3

mpls 经典MPLS学习教程

Quidway ME60 多业务控制网关 MPLS配置指南

第1章 MPLS简介

1.1.3 MPLS网络结构

1. MPLS网络结构

如图1-3所示,MPLS网络的基本构成单元是LSR,由LSR构成的网络称为MPLS域(MPLS Domain)。(www.61k.com)

位于MPLS域边缘、连接其它用户网络的LSR称为边缘LSR,即LER(Label Edge Router),区域内部的LSR称为核心LSR。核心LSR可以是支持MPLS的路由器,也可以是由ATM交换机等升级而成的ATM-LSR。域内部的LSR之间使用MPLS通信,MPLS域的边缘由LER与传统IP技术进行适配。

分组被打上标签后,沿着由一系列LSR构成的标签交换路径LSP传送。其中,入节点LER被称为Ingress,出节点LER被称为Egress,中间的节点则称为Transit。

MPLS Edge

Router(LER)

图1-3 MPLS网络结构 Label Switched Path (LSP)

mpls 经典MPLS学习教程

结合上图简要介绍MPLS的基本工作过程:

(1) LDP和传统路由协议(如OSPF、ISIS等)一起,在各个LSR中为有业务需

求的FEC建立路由表和标签映射表;

(2) 入节点Ingress接收分组,完成第三层功能,判定分组所属的FEC,并给分组

加上标签,形成MPLS标签分组,转发到中间节点Transit;

(3) Transit根据分组上的标签以及标签转发表进行转发,不对标签分组进行任何

第三层处理;

(4) 在出节点Egress去掉分组中的标签,继续进行后面的转发。

由此可以看出,MPLS并不是一种业务或者应用,它实际上是一种隧道技术,也是一种将标签交换转发和网络层路由技术集于一身的路由与交换技术平台。这个平台不仅支持多种高层协议与业务,而且,在一定程度上可以保证信息传输的安全性。

1-4

mpls 经典MPLS学习教程

[www.61k.com]

61阅读请您转载分享:

二 : Oracle经典入门教程

走进Oracle ......................................................................................................................... 2

1.

2.

3.

4.

5.

6.

7.

8. Oracle简介 ....................................................................................................................... 4 Oracle安装 ....................................................................................................................... 5 Oracle客户端工具 ......................................................................................................... 10 Oracle服务 ..................................................................................................................... 17 Oracle启动和关闭 ......................................................................................................... 18 Oracle用户和权限 ......................................................................................................... 19 本章总结 ......................................................................................................................... 22 本章练习 ......................................................................................................................... 23

SQL数据操作和查询 .......................................................................................................... 26

1.

2.

3.

4.

5.

6.

7.

8. SQL简介 ......................................................................................................................... 27 Oracle数据类型 ............................................................................................................. 27 创建表和约束 ................................................................................................................. 28 数据操纵语言(DML) ................................................................................................. 31 操作符 ............................................................................................................................. 36 高级查询 ......................................................................................................................... 37 本章总结 ......................................................................................................................... 45 本章练习 ......................................................................................................................... 46

子查询和常用函数 .............................................................................................................. 49

1.

2.

3.

4.

5. 子查询 ............................................................................................................................. 50 Oracle中的伪列 ............................................................................................................. 52 Oracle函数 ..................................................................................................................... 55 本章总结 ......................................................................................................................... 64 本章练习 ......................................................................................................................... 65

表空间、数据库对象 .......................................................................................................... 68

1.

2.

3.

4.

5.

6.

7.

8. Oracle数据库对象 ......................................................................................................... 69 同义词 ............................................................................................................................. 69 序列 ................................................................................................................................. 72 视图 ................................................................................................................................. 74 索引 ................................................................................................................................. 76 表空间 ............................................................................................................................. 78 本章总结 ......................................................................................................................... 82 本章练习 ......................................................................................................................... 83

PL/SQL程序设计 .............................................................................................................. 86

1.

2.

3.

4.

5. PL/SQL简介 .................................................................................................................... 87 PL/SQL块 ........................................................................................................................ 88 PL/SQL数据类型 ............................................................................................................ 92 PL/SQL条件控制和循环控制 ........................................................................................ 94 PL/SQL中动态执行SQL语句 ...................................................................................... 104

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

oracle教程 Oracle经典入门教程

6. PL/SQL的异常处理 ...................................................................................................... 106

7. 本章总结 ....................................................................................................................... 112

8. 本章练习 ....................................................................................................................... 113 Oracle应用于.Net平台 .................................................................................................. 115

1.

2.

3.

4.

5. 回顾ADO.NET ............................................................................................................... 116 使用ADO.NET连接Oracle .......................................................................................... 117 抽象工厂中加入Oracle ............................................................................................... 121 本章总结 ....................................................................................................................... 126 本章练习 ....................................................................................................................... 127 数据库导入导出 ................................................................................................................ 129

1.

2.

3.

4. Oracle导入导出 ........................................................................................................... 130 EXP导出数据 ................................................................................................................ 130 IMP导入 ....................................................................................................................... 133 常见问题 ....................................................................................................................... 134

第1章

走进Oracle

主要内容 ? Oracle安装

oracle教程 Oracle经典入门教程

? Oracle创建用户和角色 ? 客户端链接Oracle服务器

oracle教程 Oracle经典入门教程

1. Oracle简介

在第一学期我们已经接触过关系型数据库SQL Server,对数据库、表、记录、表的增删改查操作等这些基本的概念已经了解。[www.61k.com]Oracle是基于对象的关系型数据库,Oracle也是用表的形式对数据存储和管理,并且在Oracle的操作中添加了一些面向对象的思想。

Oracle数据库是Oracle(中文名称叫甲骨文)公司的核心产品,Oracle数据库是一个适合于大中型企业的数据库管理系统。在所有的数据库管理系统中(比如:微软的SQL Server,IBM的DB2等),Oracle的主要用户涉及面非常广,包括:银行、电信、移动通信、航空、保险、金融、电子商务和跨国公司等。Oracle产品是免费的,可以在Oracle官方网站上下载到安装包,另一方面Oracle服务是收费的。

Oracle公司成立以来,从最初的数据库版本到Oracle7、Oracle8i、Oracle9i,Oracle10g到Oracle11g,虽然每一个版本之间的操作都存在一定的差别,但是Oracle对数据的操作基本上都遵循SQL标准。因此对Oracle开发来说版本之间的差别不大。

很多人没有学习Oracle就开始发怵,因为人们在误解Oracle,认为Oracle太难学了,认为Oracle不是一般人用的数据库,其实任何数据库对应用程序研发人员来说,都是大同小异,因为目前多数数据库都支持标准的SQL。在Oracle这本书中,我们能学习到:

? Oracle的安装

? Oracle数据管理

? 常用子查询及常用函数

? PL/SQL编程

? Oracle基本管理

由于在第一学期已经接触了SQL Server,Oracle数据库的概念不是很难,主要是实践,因此在本书的学习中,认真的完成上机练习是学习好本书的关键。

接下来我们先从Oracle安装开始,接触一些Oracle中基本的概念。

oracle教程 Oracle经典入门教程

2. Oracle安装

Oracle数据库产品是免费的,我们可以从Oracle的官方网站(http://www.oracle.com)下载到程序安装包,Oracle在Windows下的安装非常方便,安装开始后,一直点击安装程序的“下一步”即可。[www.61k.com)

1. 下载Oracle10g后,解压到一个文件夹下,单击“setup.exe”文件即可启动安装界

面。如下图:

oracle教程 Oracle经典入门教程

图1 Oracle安装启动界面

Oracle主目录位置就是Oracle准备安装的位置,称为“Oracle_Home”,一般Oracle根据当前计算机的硬盘大小默认给出一个合适的位置。Oracle安装时可以只安装Oracle软件,然后单独创建数据库,也可以在上图中选中“创建启动数据库”复选框,在安装Oracle产品时,同时创建一个数据库,对初学者来说,推荐这样安装。填写全局数据库名,以及管理员的密码。全局数据库名是数据库在服务器网络中的唯一标识。

2. 点击“下一步”,就会出现如下图内容,开始对Oracle服务器进行环境检查,主要

查看服务器是否符合Oracle安装的条件,比如操作系统是否支持、系统内存是否符合Oracle安装的最低要求等。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图2 Oracle安装前环境检查

3. Oracle检查通过后,单击“下一步”,就会列出所有安装Oracle过程中的默认选项。[www.61k.com)

oracle教程 Oracle经典入门教程

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

图3 Oracle默认安装设置

4. 单击“安装”按钮,进入安装界面,这一过程经历时间比较长,根据计算机的性能

不同有很大差别。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图4 Oracle安装

5. 上图完成后,进入了各种Oracle工具的安装阶段,包括网络配置向导,iSQL*plus

等(后面课程中讲解)。(www.61k.com)如下图所示:

oracle教程 Oracle经典入门教程

图5 Oracle各种工具的安装

6. 接下来自动启动DBCA(Database Configuration Assistant)进入创建默认数据库阶段。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图6 DBCA下安装数据库

Oracle中的数据库主要是指存放数据的文件,这些文件在Oracle安装完成后,在计算机

oracle教程 Oracle经典入门教程

数据库创建后会有一系列为该数据库提供服务的内存空间和后台进程,称为该数据库的实例。[www.61k.com)每一个数据库至少会有一个实例为其服务。实例中的内存结构称为系统全局区(SGA),系统会根据当前计算机系统的性能给SGA分配非常可观的内存空间。

Oracle创建数据库不能像SQL Server那样用一个简单的CREATE DATABASE命令就能完成,在创建数据库的过程中还需要配置各种参数。虽然有DBCA工具向导,但是仍然需要进行比较麻烦的配置。

硬盘上都能找到,包括数据文件、控制文件和数据库日志文件。

7. 数据库创建完毕后,需要设置数据库的默认用户。Oracle中为管理员预置了两个用

户分别是SYS和SYSTEM。同时Oracle为程序测试提供了一个普通用户scott,口令

管理中,可以对数据库用户设置密码,设置是否锁定。 Oracle客户端使用用户名

和密码登录Oracle系统后才能对数据库操作。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图7 DBCA下的口令管理

oracle教程 Oracle经典入门教程

图8 为system,sys,scott用户设置密码

默认的用户中,SYS和SYSTEM用户是没有锁定的,安装成功后可以直接使用,SCOTT用户默认为锁定状态,因此不能直接使用,需要把SCOTT用户设定为非锁定状态才能正常使用。[www.61k.com)

这一步完成后,Oracle系统安装成功。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

3. Oracle客户端工具

Oracle服务器安装成功后,就可以通过客户端工具连接Oracle服务器了,可以到

oracle教程 Oracle经典入门教程

Oracle官方下载Oracle专用的客户端软件,大多客户端工具都是基于Oracle客户端软件的。[www.61k.com]接下来介绍几种常用的Oracle客户端工具。

? SQL*Plus工具

该工具是Oracle系统默认安装下,自带的一个客户端工具。在Windows命令行中输入“sqlplusw”命令,就能够启动该工具了。

图9 SQL*Plus工具

输入用户名和密码后,如果SQL*Plus

oracle教程 Oracle经典入门教程

与数据库服务器在同一台计算机上,并且当前服务器下只有一个数据库实例,那么“主机字符串”可以不用填写。

oracle教程 Oracle经典入门教程

SQL*Plus连接成功后就如图所示:

oracle教程 Oracle经典入门教程

图10 SQL*Plus工具登录后

? SQL*Plus命令行工具

该命令行工具,提供了与数据库交互的能力和维护数据库的能力,包括了Oracle自带的SQL*Plus工具的全部功能,在Oracle管理中经常使用。(www.61k.com)在命令行中输入:“sqlplus /nolog”即可启动该工具。如下图:

oracle教程 Oracle经典入门教程

图11 启动SQL*Plus命令行工具

conn 用户名/密码 as 连接身份@服务器连接字符串

说明:

1. 连接身份:表示该用户连接后拥有的权限。 输入“sqlplus /nolog”命令后,只是启动了一个客户端进程,并没有与服务器连接,连接到Oracle服务器的命令是:

oracle教程 Oracle经典入门教程

? sysdba: 即数据库管理员,权限包括:打开数据库服务器、关闭数据库服务

器、备份数据库、恢复数据库、日志归档、会话限制、管理功能、创建数据库。(www.61k.com)

sys用户必须用sysdba身份才能登录,system用户可以用普通身份登录。

? sysyoper:即数据库操作员,权限包括:打开数据库服务器、关闭数据库服务

器、备份数据库、恢复数据库、日志归档、会话限制。

? normal:即普通用户,权限只有查询某些数据表的数据。默认的身份是normal

用户。

2. 客户端工具可以根据“服务器连接字符串”对服务器进行连接,有了连接字符串后

客户端就可以像操作本机一样操作远程数据库,因此“服务器连接字符串”的配置也叫本地网络服务配置,如果SQL*Plus工具启动在服务器上,并且服务器上只有一个数据库实例的情况下,连接字符串可以缺省,在连接字符串中包括连接服务器的协议,服务器的地址,服务器的端口等设置,Oracle服务名等,该配置文件在Oracle安装目录下的: network/ADMIN/ tnsnames.ora。该文件是一个文本文件,用记事本打开后如下所示:

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

oracle教程 Oracle经典入门教程

图12 服务器连接字符串配置

? 配置本地网络服务名

本地网络服务名,即客户端与服务器的连接字符串,本地网络服务名是客户端的配置,Oracle客户端安装后,可以使用客户端自带的网络配置向导(Net Configuration Assistant)进行配置:

1. 启动Net Configuration Assistant。选择“本地Net服务名配置”选项。如下图所示:

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图13 启动Net Configuration Assistant

2. 选择“下一步”,本步骤可以对本地网络服务名进行添加,删除,测试是否正常连

接等操作,选择“添加”选项。(www.61k.com]

oracle教程 Oracle经典入门教程

图14 Net Configuration Assistant

3. 点击“下一步”,填写服务名,该服务名就是Oracle安装时(图1),为数据库取的

全局数据库名。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图15 服务名配置

4. 点击“下一步”,选择服务需要的协议,默认是TCP协议。[www.61k.com]推荐使用默认的TCP协

议。

oracle教程 Oracle经典入门教程

图16 选择协议

5. 点击“下一步”,输入主机名,主机名可以是计算机名称,也可以是一个IP地址,

主机如果是本机,可以使用本机计算机名称、“localhost”、“127.0.0.1”、或者本机的IP地址。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图17 输入主机名和端口

6. 单击“下一步”,选择“是,进行测试”选项。(www.61k.com)进入下图界面。

oracle教程 Oracle经典入门教程

图18 测试成功

在测试时,默认采用的用户名和密码是system/manager进行测试,如果用户system的密码不是“manager”,有可能测试通不过,更改登录后,输入正确的用户名和密码后再进行测试即可。

7. 测试成功后,单击“下一步”,出现如下界面,这一步是为本地网络服务命名,即

图12中的服务器连接字符串名。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图19 为网络服务名命名

点击“下一步”,配置就完成了,进入tnsnames.ora文件中查看,就出现了如图12中的内容。[www.61k.com)

? PL/SQL Developer工具

在实际Oracle开发中,经常使用一个功能强大的第三方工具:“PL/SQL Developer”工具。PL/SQL Developer基本上可以实现Oracle开发中的任何操作。它运行在客户端时必须先安装Oracle客户端,并且通过网络配置向导配置网络服务名后才能正常与服务器连接。

oracle教程 Oracle经典入门教程

图20 PL/SQL Developer

oracle教程 Oracle经典入门教程

4. Oracle服务

Oracle在windows中安装完成后,会安装很多服务,下面介绍几个主要的服务。[www.61k.com)

oracle教程 Oracle经典入门教程

图21 Oracle服务

? OracleService+服务名,该服务是数据库启动的基础,只有该服务启动了,Oracle数

据库才能正常启动。这是必须启动的服务。

? OracleOraDb10g_home1TNSListener,该服务是服务器端为客户端提供的监听服务,

只有该服务在服务器上正常启动,客户端才能连接到服务器。该监听服务接收客户端发出的请求,然后将请求传递给数据库服务器。一旦建立了连接,客户端和数据库服务器就能直接通信了。

? OracleOraDb10g_home1iSQL*Plus,该服务提供了用浏览器对数据库中数据操作的方

式。该服务启动后,就可以使用浏览器进行远程登录并进行数据库操作了。如下图所示:

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图22 iSQL*Plus

? OracleDBConsole+服务名,Oracle10g中的一个新服务。[www.61k.com]在Oracle9i之前,Oracle官

方提供了一个基于图形界面的企业管理器(EM),从Oracle10g开始,Oracle提供了一个基于B/S的企业管理器,在操作系统的命令行中输入命令:emctl start

dbconsole,就可以启动OracleDbConsole服务,如下图所示:

oracle教程 Oracle经典入门教程

图23 EM服务的启动

服务启动之后,就可以在浏览器中输入上图中进入EM的地址,使用B/S方式管理Oracle服务器。

5. Oracle启动和关闭

OracleService启动动后,就可以对数据库进行管理了,Oracle的启动和关闭是最基本的命令,在SQL*Plus中,启动Oracle必须是sys用户,命令格式是:

oracle教程 Oracle经典入门教程

startup open

oracle教程 Oracle经典入门教程

图24 Oracle服务启动

Oracle服务关闭用命令:shutdown immediate

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

oracle教程 Oracle经典入门教程

图25 Oracle服务关闭

6. Oracle用户和权限 Oracle中,一般不会轻易在一个服务器上创建多个数据库,在一个数据库中,不同的项目由不同的用户访问,每一个用户拥有自身创建的数据库对象,因此用户的概念在Oracle中非常重要。(www.61k.com)Oracle的用户可以用CREATE USER命令来创建。其语法是:

语法结构:创建用户

CREATE USER 用户名 IDENTIFIED BY 口令 [ACCOUNT LOCK|UNLOCK]

oracle教程 Oracle经典入门教程

语法解析:

代码演示:创建用户

SQL> CREATE USER jerry

2 IDENTIFIED BY tom

3 ACCOUNT UNLOCK; LOCK|UNLOCK创建用户时是否锁定,默认为锁定状态。[www.61k.com)锁定的用户无法正常的登录进行数据库操作。

oracle教程 Oracle经典入门教程

Oracle用户对数据库管理或对象操作的权利,分为系统权限和数据库对象权限。系统权限比如:CREATE SESSION,CREATE TABLE等,拥有系统权限的用户,允许拥有相应的系统操作。数据库对象权限,比如对表中的数据进行增删改操作等,拥有数据库对象权限的用户可以对所拥有的对象进行对应的操作。

还有一个概念就是数据库角色(role),数据库角色就是若干个系统权限的集合。下面

? CONNECT角色,主要应用在临时用户,特别是那些不需要建表的用户,通常只赋予

他们CONNECT role。CONNECT是使用Oracle的简单权限,拥有CONNECT角色的用户,可以与服务器建立连接会话(session,客户端对服务器连接,称为会话)。

? RESOURCE角色,更可靠和正式的数据库用户可以授予RESOURCE role。RESOURCE

提供给用户另外的权限以创建他们自己的表、序列、过程(procedure)、触发器

(trigger)、索引(index)等。

? DBA角色,DBA role拥有所有的系统权限----包括无限制的空间限额和给其他用户授

予各种权限的能力。用户SYSTEM拥有DBA角色。

一般情况下,一个普通的用户(如SCOTT),拥有CONNECT和RESOURCE两个角色即可进行常规的数据库开发工作。

介绍几个常用角色: 尽管用户成功创建,但是还不能正常的登录Oracle数据库系统,因为该用户还没有任何权限。如果用户能够正常登录,至少需要CREATE SESSION系统权限。

oracle教程 Oracle经典入门教程

可以把某个权限授予某个角色,可以把权限、角色授予某个用户。[www.61k.com]系统权限只能由DBA用户授权,对象权限由拥有该对象的用户授权,授权语法是:

语法结构:授权

GRANT角色|权限 TO 用户(角色)

代码演示:授权

SQL> GRANT CONNECT TO jerry;

授权成功。

SQL> GRANT RESOURCE TO jerry; 授权成功。 SQL>

语法结构:其他操作

//回收权限

REVOKE 角色|权限 FROM 用户(角色) //修改用户的密码

ALTER USER 用户名 IDENTIFIED BY 新密码 //修改用户处于锁定(非锁定)状态

ALTER USER 用户名 ACCOUNT LOCK|UNLOCK

oracle教程 Oracle经典入门教程

7. 本章总结

? Oracle是基于对象的关系型数据库,Oracle产品免费,服务收费。[www.61k.com)

? Oracle安装后默认会有两个管理员用户(system,sys)和一个普通用户Scott。 ? Sql*plus是Oracle管理和数据操作的客户端工具。

? 客户端链接服务器前,服务器要启动监听服务,并且客户端工具要安装Oracle客

户端,并且在客户端要建立本地网络服务名。

? Oracle服务和监听启动后才能对数据库进行操作。

? 用startup命令启动数据库,用shutdown命令关闭数据库。

? Oracle的角色包括了一系列系统权限和普通对象权限,可以把权限授权给角色,把

权限或者角色授权给用户。

oracle教程 Oracle经典入门教程

8. 本章练习

1. 描述Oracle安装过程中的关键点。(www.61k.com]

2. 描述创建本地网络服务名的步骤。

3. 描述Oracle主要服务的作用。

4. Oracle使用什么命令才能启动和关闭。

5. 什么是Oracle权限和角色?他们的关系是什么?

6. 创建一个用户,并授权CONNECT和RESOURCE。

oracle教程 Oracle经典入门教程

章节知识结构图

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

[www.61k.com]

oracle教程 Oracle经典入门教程

第2章

SQL数据操作和查询

主要内容 ? Oracle数据类型

? SQL建表和约束

? SQL对数据增删改

? SQL查询

? Oracle伪列

oracle教程 Oracle经典入门教程

1. SQL简介

在第一学期的SQL Server学习中,已经知道,SQL是结构化查询语言(Structured Query Language),专门用于数据存取、数据更新及数据库管理等操作。(www.61k.com]并且已经学习了用SQL语句对数据库的表进行增删改查的操作。

在Oracle开发中,客户端把SQL语句发送给服务器,服务器对SQL语句进行编译、执行,把执行的结果返回给客户端。Oracle SQL语句由如下命令组成:

? 数据定义语言(DDL),包括CREATE(创建)命令、ALTER(修改)命令、DROP(删

除)命令等。

? 数据操纵语言(DML),包括INSERT(插入)命令、UPDATE(更新)命令、DELETE

(删除)命令、SELECT … FOR UPDATE(查询)等。

? 数据查询语言(DQL),包括基本查询语句、Order By子句、Group By子句等。 ? 事务控制语言(TCL),包括COMMIT(提交)命令、SAVEPOINT(保存点)命令、

ROLLBACK(回滚)命令。

? 数据控制语言(DCL),GRANT(授权)命令、REVOKE(撤销)命令。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

目前主流的数据库产品(比如:SQL Server、Oracle)都支持标准的SQL语句。数据定义语言,表的增删改操作,数据的简单查询,事务的提交和回滚,权限的授权和撤销等,Oracle与SQL Server在操作上基本一致。

2. Oracle数据类型

Oracle数据库的核心是表,表中的列使用到的常见数据类型如下:

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表1 Oracle的部分数据类型

oracle教程 Oracle经典入门教程

对应NUMBER类型的示例: 表2 Number示例

oracle教程 Oracle经典入门教程

对于日期类型,可以使用sysdate内置函数可以获取当前的系统日期和时间,返回DATE类型,用systimestamp函数可以返回当前日期、时间和时区。(www.61k.com]

图1 sysdate和sysTimestamp

Oracle的查询中,必须使用“select 列… from 表”的完整语法,当查询单行函数的时候,from后面使用DUAL表,dual表在系统中只有一行一列,该表在输出单行函数时为了select…from的语法完整性而使用。

3. 创建表和约束

Oracle创建表同SQL Server一样,使用CREATE TABLE命令来完成。创建约束则使用如下命令:

oracle教程 Oracle经典入门教程

语法格式:ALTER TABLE命令

ALTER TABLE 表名 ADD CONSTRAINT 约束名 约束内容。[www.61k.com]

不论创建表还是约束,与SQL Server基本相同,注意:在Oracle中default是一个值,而SQL Server中default是一个约束,因此Oracle的default设置可以在建表的时候创建。

案例1:创建一个学生信息(INFOS)表和约束

代码演示:Oracle创建表和约束

oracle教程 Oracle经典入门教程

(

STUID VARCHAR2(7) NOT NULL, --学号 学号=‘S’+班号+2位序号

STUNAME VARCHAR2(10) NOT NULL, --姓名

GENDER VARCHAR2(2) NOT NULL, --性别

AGE NUMBER(2) NOT NULL, --年龄

SEAT NUMBER(2) NOT NULL, --座号

ENROLLDATE DATE, --入学时间

STUADDRESS VARCHAR2(50) DEFAULT '地址不详', --住址

CLASSNO VARCHAR2(4) NOT NULL --班号 班号=学期序号+班级序号

)

/ ①

ALTER TABLE INFOS ADD CONSTRAINT PK_INFOS PRIMARY KEY(STUID) ②

/

ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_GENDER

CHECK(GENDER = '男' OR GENDER = '女') ③

/

ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_SEAT

CHECK(SEAT >=0 AND SEAT <=50) ④

/

ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_AGE

CHECK(AGE >=0 AND AGE<=100) ⑤

/

ALTER TABLE INFOS ADD CONSTRAINT CK_INFOS_CLASSNO

CHECK((CLASSNO >='1001' AND CLASSNO<='1999') OR

(CLASSNO >='2001' AND CLASSNO<='2999')) ⑥

/

oracle教程 Oracle经典入门教程

ALTER TABLE INFOS ADD CONSTRAINTS UN_STUNAME UNIQUE(STUNAME) ⑦ /

代码解析:

① 在Oracle代码中,“/”执行缓存区中的语句,由于缓冲区中只存储一条刚刚保存过

语句,由于每条语句没有用分号结尾,只是保存在缓冲区,因此每条语句后面都有单独一行“/”。(www.61k.com)

② 创建一个主键约束。

③ 与 ④ ⑤ ⑥ ⑦一起创建各种check约束。其中⑦是唯一约束,表示该列值是唯一

的,列中的值不能重复。

Oracle中创建外键约束与SQL Server相同。比如:现有成绩表定义如下:

案例2:创建一个成绩表(SCORES)表和约束

代码演示:Oracle创建表和约束

CREATE TABLE SCORES (

ID NUMBER , --ID ①

TERM VARCHAR2(2),

--学期 S1或S2 --学号 --考号 E+班号+序号 STUID VARCHAR2(7) NOT NULL, EXAMNO VARCHAR2(7) NOT NULL,

WRITTENSCORE NUMBER(4,1) NOT NULL, --笔试成绩

LABSCORE NUMBER(4,1) NOT NULL

)

ALTER TABLE SCORES

ADD CONSTRAINT CK_SCORES_TERM CHECK(TERM = 'S1' OR TERM ='S2') /

ALTER TABLE SCORES INFOS(STUID) ②

/ --机试成绩

代码解析:

① SQL Server中可以使用identify创建自动增长列,但是Oracle中的自动增长需要借助

序列(Sequence)完成,在后面章节中讲解。

② Oracle中的外键约束定义。

oracle教程 Oracle经典入门教程

4. 数据操纵语言(DML)

数据操纵语言(DML)用于对数据库的表中数据进行添加、修改、删除和SELECT…For UPDATE(后面专门学习该查询)操作。[www.61k.com)对比一期学习过的SQL Server操作,接下来一一介绍在Oracle中的操作。

? 简单查询

数据查询是用SELECT命令从数据库的表中提取信息。SELECT语句的语法是:

语法结构:简单查询

SELECT *|列名|表达式 FROM 表名 WHERE 条件 ORDER BY 列名

语法解析:

1. *表示表中的所有列。

2. 列名可以选择若干个表中的列名,各个列表中间用逗号分隔。

3. 表达式可以是列名、函数、常数等组成的表达式。

4. WHERE子句是查询的条件。

5. ORDER BY 要求在查询的结果中排序,默认是升序。

oracle教程 Oracle经典入门教程

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

图2 数据查询

oracle教程 Oracle经典入门教程

Oracle中可以把查询的结果根据结果集中的表结构和数据形成一张新表。(www.61k.com)

语法结构:根据结果集创建表

CREATE TABLE 表名 AS SELECT语句

代码演示:根据结果集创建表

SQL> CREATE TABLE INFOS1 AS SELECT * FROM INFOS; TABLE CREATED

使用上面命令创建的新表中,不存在任何约束,并且把查询的数据一起插入到新表中。如果只复制表结构,只需使查询的条件不成立(比如where 1=2),就不会查询从出任何数据,从而复制一个表结构。

代码演示:复制表结构

SQL> CREATE TABLE INFOS2 AS SELECT * FROM INFOS WHERE 1=2; TABLE CREATED

? 数据插入

用INSERT命令完成对数据的插入。

语法结构:根据结果集创建表

INSERT INTO 表名(列名1,列名2……) VALUES (值1,值2……)

语法解析:

1. 列名可以省略。当省略列名时,默认是表中的所有列名,列名顺序为表定义中列的

先后顺序。

2. 值的数量和顺序要与列名的数量和顺序一致。值的类型与列名的类型一致。

代码演示:向INFOS表和SCORES表中插入数据

SQL> INSERT INTO INFOS VALUES ( ①

2 's100102', '林冲', '男', 22, 2,

3 TO_DATE('2009-8-9 06:30:10',' YYYY-MM-DD HH24:MI:SS '), ②

oracle教程 Oracle经典入门教程

4 '西安', '1001'

5 )

6 /

1 row inserted

SQL> INSERT INTO INFOS VALUES (

's100104','阮小二','男',26,3,SYSDATE,default,'1001'); ③

1 row inserted

SQL>COMMIT; ④

代码解析:

① 表名后面缺省了列名,默认是表Infos中的所有列名,values中的值要与表中列一一

对应,包括顺序和数据类型的对应。[www.61k.com]在SQL*Plus中一条语句可以写在多行,那么从第二行开始,sqlplus会为每一行前面给出行号。

② 在Oracle中,日期是国际化的,不同的区域安装的数据库,默认的日期格式不同,

因此为了程序便于移植,日期的输入要使用TO_DATE函数对日期格式化后输入,采用格式化字符串对日期进行格式化时,格式化字符串中字符不区分大小写,常见的格式化字符如下:

1. yyyy表示四位年份

2. mm表示两位月份,比如3月表示为03

3. dd表示两位日期

4. hh24表示小时从0-23,hh12也表示小时从0-11。

5. mi 表示分钟

6. ss表示秒

③ 在遇到存在默认值的列时,可以使用default值代替。

④ commit是把用户操作(添加、删除、修改操作)提交,只有提交操作后,数据才

能真正更新到表中,否则其他用户无法查询到当前用户操作的结果。

在Oracle中,一个INSERT命令可以把一个结果集一次性插入到一张表中。使用的语句是:INSERT INTO 表 SELECT子句,如下示例:

代码演示:INSERT向表中插入一个结果集

SQL> INSERT INTO INFOS2 SELECT * FROM INFOS;

5 rows inserted

在这种语法下,要求结果集中每一列的数据类型必须与表中的每一列的数据类型一致,结果集中的列的数量与表中的列的数量一致。比如表INFOS2,该表的结构与INFO表一样,那么可以把INFO表中的所有记录一次性插入到INFOS2表中。

oracle教程 Oracle经典入门教程

Oracle的简单查询和SQL Server一样都可以在查询列中使用常量,如图:

oracle教程 Oracle经典入门教程

图3 Select中的常量

可以使用刚才的做法,把该结果集中的数据插入到表INFOS中。(www.61k.com)

代码演示:INSERT向表中插入一个常量结果集

SQL> INSERT INTO INFOS

SELECT 's100106','卢俊义','男',23,5,

TO_DATE('2009-8-9 08:00:10','YYYY-MM-DD HH24:MI:SS'), '青龙寺','1001'

FROM DUAL;

1 rows inserted SQL>COMMIT;

? 更新数据

Oracle在表中更新数据的语法是:

语法结构:UPDATE操作

UPDATE 表名 SET 列名1=值,列名2=值…… WHERE 条件

代码演示:UPDATE操作

oracle教程 Oracle经典入门教程

SQL> UPDATE INFOS SET CLASSNO='1002',STUADDRESS='山东莱芜'

WHERE STUNAME='阮小二';

1 rows updated SQL> commit;

? 删除数据

Oracle在表中删除数据的语法是:

语法结构:DELETE操作

DELETE FROM表名 WHERE 条件

代码演示:DELETE操作

SQL> DELETE FROM INFOS WHERE STUID='s100103';

1 ROW DELETED SQL> COMMIT;

? TRUNCATE

在数据库操作中, TRUNCATE命令(是一个DDL命令)可以把表中的所有数据一次性全部删除,语法是:

语法结构:TRUNCATE

TRUNCATE TABLE 表名

TRUNCATE和DELETE都能把表中的数据全部删除,他们的区别是:

1. TRUNCATE是DDL命令,删除的数据不能恢复;DELETE命令是DML命令,删除后

的数据可以通过日志文件恢复。[www.61k.com)

2. 如果一个表中数据记录很多,TRUNCATE相对DELETE速度快。

由于TRUNCATE命令比较危险,因此在实际开发中,TRUNCATE命令慎用。

oracle教程 Oracle经典入门教程

5. 操作符

Oracle开发中,依然存在算术运算,关系运算,和逻辑运算。(www.61k.com)

? 算术运算

Oracle中的算术运算符,没有C#中的算术运算符丰富,只有+、-、*、/四个,其中除号(/)的结果是浮点数。求余运算只能借助函数:MOD(x,y):返回x除以y的余数。

案例3:每名员工年终奖是2000元,请显示基本工资在2000元以上的员工的月工资,年总工资。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

该案例的表请参见本章练习的附表1、附表2、附表3,这三张表是ORACLE 10g自带的。

代码演示:查询中的算术运算

SQL> SELECT ENAME,SAL,(SAL*12+2000) FROM EMP WHERE SAL>2000;

ENAME

JONES

BLAKE

CLARK

SCOTT

KING

FORD SAL 2975 2850 2450 3000 5000 3000 (SAL*12+2000) 37700 36200 31400 38000 62000 38000 6 rows selected

? 关系运算和逻辑运算

Oracle中Where子句经中经常见到关系运算和逻辑运算,常见的关系运算有:

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表3 Oracle的关系运算符

逻辑运算符有三个:AND、OR、NOT

关系运算和逻辑运算与前面SQL Server学习过的一致。[www.61k.com]

? 字符串连接操作符(||)

在Oracle中,字符串的连接用双竖线(||)表示。比如,在EMP表中,查询工资在2000元以上的姓名以及工作。

代码演示:字符串连接

SQL> SELECT (ENAME || 'is a ' || JOB) AS "Employee Details" ①

2 FROM EMP

3 WHERE SAL>2000;

Employee Details

------------------------

JONESis a MANAGER

BLAKEis a MANAGER

CLARKis a MANAGER

SCOTTis a ANALYST

KINGis a PRESIDENT

FORDis a ANALYST

6 rows selected

代码解析:

① Oracle中字符串可以用单引号,也可以用双引号,在别名中存在空格时,必须用双

引号。在表名、列名时用双引号。

6. 高级查询

在第一期学习过SQL的简单查询和连接查询。现在学习一些新的SQL操作符。

oracle教程 Oracle经典入门教程

? 消除重复行

在Oracle查询中结果中,可能出现若干行相同的情况,那么可以使用DISTINCT消除重复行。[www.61k.com)具体的用法如示例:

代码演示:DISTINCT消除重复行

SQL> SELECT DISTINCT DEPTNO FROM EMP;

DEPTNO

------

30

20

10

? NULL操作

如果某条记录中有缺少的数据值,就是空值(NULL值)。空值不等于0或者空格,空值是指未赋值、未知或不可用的值。任何数据类型的列都可以包括NULL值,除非该列被定义为非空或者主键。

代码演示:EMP中的NULL值

SQL> SELECT ENAME,JOB,SAL,COMM FROM EMP WHERE SAL<2000;

ENAME

SMITH

ALLEN

WARD

MARTIN

TURNER

ADAMS

JAMES JOB CLERK SALESMAN SALESMAN SALESMAN SALESMAN CLERK CLERK SAL 800 1600 1250 1250 1500 1100 950 COMM 300 500 1400 0 7 rows selected

在查询条件中NULL值用IS NULL作条件,非NULL值用NOT IS NULL做条件。

oracle教程 Oracle经典入门教程

案例4:查询EMP表中没有发奖金的员工。[www.61k.com)

代码演示:NULL值查询

SQL> SELECT ENAME,JOB,SAL,COMM FROM EMP

2 WHERE SAL<2000 AND COMM IS NULL;

ENAME

SMITH

ADAMS

JAMES

MILLER JOB CLERK CLERK CLERK CLERK SAL 800 1100 950 1300 COMM

? IN 操作

在Where子句中可以使用IN操作符来查询其列值在指定的列表中的行。比如:查询出工作职责是SALESMAN、PRESIDENT或者ANALYST的员工。条件有两种表示方法:

1. WHERE job = 'SALESMAN ' OR job = 'PRESIDENT ' OR job = 'ANALYST '

2. WHERE job IN ('SALESMAN', 'PRESIDENT', 'ANALYST')

代码演示:IN操作

SQL> SELECT ENAME,JOB,SAL FROM EMP

2 WHERE job IN ('SALESMAN', 'PRESIDENT', 'ANALYST');

ENAME

ALLEN

WARD

MARTIN

SCOTT

KING

TURNER

FORD

7 rows selected JOB SALESMAN SALESMAN SALESMAN ANALYST PRESIDENT SALESMAN ANALYST SAL 1600 1250 1250 3000 5000 1500 3000

对应IN操作的还有NOT IN,用法一样,结果相反。

oracle教程 Oracle经典入门教程

? BETWEEN…AND…

在WHERE子句中,可以使用BETWEEN操作符来查询列值包含在指定区间内的行。(www.61k.com]比如,查询工资从1000到2000之间的员工。可以使用传统方法:

代码演示:BETWEEN操作

oracle教程 Oracle经典入门教程

ENAME

ALLEN

WARD

MARTIN

TURNER

ADAMS

MILLER JOB SALESMAN SALESMAN SALESMAN SALESMAN CLERK CLERK SAL 1600 1250 1250 1500 1100 1300 WHERE SAL>=1000 AND SAL<=2000 也可以使用: WHERE SAL BETWEEN 1000 AND 2000 BWTWEEN操作所指定的范围也包括边界。

6 rows selected

? LIKE模糊查询

在一些查询时,可能把握不准需要查询的确切值,比如百度搜索时输入关键字即可查询出相关的结果,这种查询称为模糊查询。模糊查询使用LIKE关键字通过字符匹配检索出所需要的数据行。字符匹配操作可以使用通配符“%”和“_”:

? %:表示零个或者多个任意字符。

? _:代表一个任意字符。

语法是:LIKE '字符串'[ESCAPE '字符']。匹配的字符串中,ESCAPE后面的“字符”作为转义字符。与一期SQLServer

oracle教程 Oracle经典入门教程

中ESCAPE用法相同。

oracle教程 Oracle经典入门教程

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

oracle教程 Oracle经典入门教程

表4 通配符示例

案例5:显示员工名称以J开头以S结尾的员工的姓名、工资和工资。(www.61k.com)

代码演示:LIKE操作

oracle教程 Oracle经典入门教程

ENAME JOB SAL

---------- --------- ---------

JONES MANAGER 2975.00

JAMES CLERK 950.00

? 集合运算

集合运算就是将两个或者多个结果集组合成为一个结果集。集合运算包括: ?

oracle教程 Oracle经典入门教程

INTERSECT(交集),返回两个查询共有的记录。

? UNION ALL(并集),返回各个查询的所有记录,包括重复记录。

? UNION(并集),返回各个查询的所有记录,不包括重复记录。

? MINUS(补集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩

余的记录。

当使用集合操作的时候,要注意:查询所返回的列数以及列的类型必须匹配,列名可以不同。

案例6:查询出dept表中哪个部门下没有员工。只需求出dept表中的部门号和emp表中的部门号的补集即可。

代码演示:求补运算

2 MINUS

3 SELECT DEPTNO FROM EMP;

DEPTNO

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

40

代码演示:用union插入多条数据

oracle教程 Oracle经典入门教程

2 SELECT 50,'公关部','台湾' FROM DUAL

3 UNION

4 SELECT 60,'研发部','西安' FROM DUAL

5 UNION

6 SELECT 70,'培训部','西安' FROM DUAL

7 /

3 rows inserted 前面学习过可以通过insert into …select把一个结果集插入到另一张结构相同的表中,因此可以使用union把若干条记录一次性插入到一张表中。[www.61k.com]

? 连接查询

在SQL Server中已经学习过内联接(inner join)、外联接(outer join),外联接又分为左外联接(left outer join)和右外联接(right outer join)。Oracle中对两个表或者若干表之间的外联接用(+)表示。

案例7:请查询出工资大于2000元的,员工姓名,部门,工作,工资。

由于部门名称在dept中,其他的信息在emp表中,需要内联接才能完成。

代码演示:内联接

oracle教程 Oracle经典入门教程

2 FROM emp e,dept d

3 WHERE e.deptno=d.deptno

4 AND e.SAL>2000;

ENAME

JONES

BLAKE

CLARK JOB MANAGER MANAGER MANAGER SAL 2975 2850 2450 DNAME RESEARCH SALES ACCOUNTING

oracle教程 Oracle经典入门教程

SCOTT KING FORD

6 rows selected

ANALYST PRESIDENT ANALYST

3000 5000 3000

RESEARCH ACCOUNTING RESEARCH

代码演示:内联接

SELECT e.ENAME,e.JOB,e.SAL,d.DNAME

FROM EMP e INNER JOIN DEPT d ON e.DEPTNO=d.DEPTNO WHERE e.SAL>2000

也可以使用SQL/92标准中的内联接:

这里INNER JOIN中,关键字INNER可以省略。[www.61k.com)

案例8:请查询出每个部门下的员工姓名,工资。 案例分析:

Emp表用外键deptno引用Dept表中的deptno,在Dept表中如果有某些部门没有员工,那么用内联接,没有员工的部门将无法显示,因此必须以Dept表为基准的外联接。

代码演示:外联接

oracle教程 Oracle经典入门教程

2 FROM EMP e ,DEPT d

3 WHERE e.DEPTNO(+)=d.DEPTNO ① 4 / ENAME SMITH ALLEN WARD JONES MARTIN BLAKE CLARK SCOTT

JOB CLERK SALESMAN SALESMAN MANAGER SALESMAN MANAGER MANAGER ANALYST

SAL 800 1600 1250 2975 1250 2850 2450 3000

DNAME RESEARCH SALES SALES RESEARCH SALES SALES ACCOUNTING RESEARCH

oracle教程 Oracle经典入门教程

KING

TURNER

ADAMS

JAMES

FORD

MILLER

PRESIDENT SALESMAN CLERK CLERK ANALYST CLERK 5000 1500 1100 950 3000 1300 ACCOUNTING SALES RESEARCH SALES RESEARCH ACCOUNTING 公关部 研发部 培训部 OPERATIONS 18 rows selected

代码解析:

oracle教程 Oracle经典入门教程

(+):Oracle专用的联接符,在条件中出现在左边指右外联接,出现在右边指左外

联接。(www.61k.com)

代码演示:外联接

SELECT e.ENAME,e.JOB,e.SAL,d.DNAME

FROM EMP e RIGHT OUTER JOIN DEPT d ON e.DEPTNO=d.DEPTNO 也可以使用SQL/92标准的写法:

这里RIGHT OUTER JOIN中,关键字OUTER可以省略。

oracle教程 Oracle经典入门教程

7. 本章总结

? Oracle SQL语句中有数据操纵语言(DML)、数据定义语言(DDL)、数据控制语言

(DCL)、事务控制语言(TCL)等等。(www.61k.com]

? DML语句包括增删改查语句,DDL语句包括数据库对象创建、修改和删除语句,数

据控制命令包括GRANT、REVOKE等,事务控制命令有COMMIT、ROLLBACK等。 ? 数据库中建表常用的类型有:数字类型number(p,s),可变字符串varchar2(length),

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

日期date。

? Oracle中default是一个值,在Oracle中不存在default约束。

? Oracle的增删改语句与SQL Server基本一致,都是使用INSERT、UPDATE、DELETE

完成。

? Oracle高级查询中要注意:DISTINCT、NULL、IN、BETWEEN…AND…。

? 集合操作有:UNION、UNION ALL、INTESECT、MINUS。

? 联接查询有内联接和外联接。

oracle教程 Oracle经典入门教程

8. 本章练习

1. 创建一查询,显示与Blake在同一部门工作的雇员的项目和受雇日期,但是Blake

不包含在内。(www.61k.com)

2. 显示位置在Dallas的部门内的雇员姓名、变化以及工作。 3. 显示被King直接管理的雇员的姓名以及工资。

4. 创建一查询,显示能获得与Scott一样工资和奖金的其他雇员的姓名、受雇日期以

及工资。

附表1:Scott表中的EMP表:员工表

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

附表2:Scott表中的DEPT表:部门表

oracle教程 Oracle经典入门教程

附表3:Scott表中的SALGRADE表:工资等级表

oracle教程 Oracle经典入门教程

章节知识结构图

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

(www.61k.com]

oracle教程 Oracle经典入门教程

第3章

子查询和常用函数

主要内容 ? 子查询

? 伪列

? 锁的概念

oracle教程 Oracle经典入门教程

1. 子查询

子查询在SELECT、UPDATE、DELETE语句内部可以出现SELECT语句。(www.61k.com]内部的SELECT语句结果可以作为外部语句中条件子句的一部分,也可以作为外部查询的临时表。子查询的类型有:

1. 单行子查询:不向外部返回结果,或者只返回一行结果。

2. 多行子查询:向外部返回零行、一行或者多行结果。

案例1:查询出销售部(SALES)下面的员工姓名,工作,工资。

案例分析

该问题可以用联接查询实现,由于所需的结果信息都在Emp表中,可以先从Dept表中查询出销售部对应的部门号,然后根据当前部门号再到Emp表中查询出符合该部门的员工记录即可。从销售表中查询出的结果可以作为Emp表中查询的条件,SQL语句实现如下:

代码演示:单行子查询

SQL> SELECT ENAME,JOB,SAL FROM EMP

2 WHERE DEPTNO=(SELECT DEPTNO FROM DEPT WHERE DNAME='SALES') ① 3 /

ENAME

ALLEN

WARD

MARTIN

BLAKE

TURNER

JAMES JOB SALESMAN SALESMAN SALESMAN MANAGER SALESMAN CLERK SAL 1600 1250 1250 2850 1500 950

6 rows selected

代码解析:

① 内部查询的结果作为外部查询的条件。

需要注意:

oracle教程 Oracle经典入门教程

? 如果内部查询不返回任何记录,则外部条件中字段DEPTNO与NULL比较永远为假,

也就是说外部查询不返还任何结果。[www.61k.com)

? 在单行子查询中外部查询可以使用=、>、<、>=、<=、<>等比较运算符。

? 内部查询返回的结果必须与外部查询条件中的字段(DEPTNO)匹配。

? 如果内部查询返回多行结果则出现错误。

案例2:查询出Emp表中比任意一个销售员(“SALESMAN”)工资低的员工姓名、工作、工资。

案例分析

销售员在Emp表中有很多条记录,每个人工资不相等,如果返回“比任意员工的工资还低”的条件,返回比“最高工资还低”即可。如果用子查询做,子查询中就会返回多条记录。用普通的关系符(>、<等)运行就会出错。这时候需要用关键字ANY。ANY放在比较运算符后面,表示“任意”的意思。

代码演示:ANY子查询 SQL> SELECT ENAME,JOB,SAL FROM EMP

2 WHERE SAL<ANY (SELECT SAL FROM EMP WHERE JOB='SALESMAN') ①

3 /

ENAME

SMITH

JAMES

ADAMS

WARD

MARTIN

MILLER

TURNER JOB CLERK CLERK CLERK SALESMAN SALESMAN CLERK SALESMAN SAL 800 950 1100 1250 1250 1300 1500

7 rows selected

代码解析:

① <any:比子查询结果中任意的值都小,也就是说,比子查询结果中最大值还小,那么

同理>any表示比子查询结果中最小的还大。

案例3:查询出比所有销售员的工资都高的员工姓名,工作,工资。

oracle教程 Oracle经典入门教程

案例分析

ANY可以表示任意的,但本案例中要求比所有销售员工资都高,那么就要使用另外一个关键字ALL。[www.61k.com)ALL与关系操作符一起使用,表示与子查询中所有元素比较。

代码演示:ALL子查询 SQL> SELECT ENAME,JOB,SAL FROM EMP

2 WHERE SAL>ALL (SELECT SAL FROM EMP WHERE JOB='SALESMAN') ①

3 /

ENAME

JONES

BLAKE

CLARK

SCOTT

KING

FORD

6 rows selected JOB MANAGER MANAGER MANAGER ANALYST PRESIDENT ANALYST SAL 2975 2850 2450 3000 5000 3000 代码解析:

① >ALL:比子查询结果中所有值还要大,也就是说,比子查询结果中最大值还要大。

<ALL表示比最小值还要小。

对于子查询还可以使用IN和NOT IN操作符进行操作。

2. Oracle中的伪列

在Oracle的表的使用过程中,实际表中还有一些附加的列,称为伪列。伪列就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。接下来学习两个伪列:ROWID和ROWNUM。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

? ROWID

表中的每一行在数据文件中都有一个物理地址,ROWID伪列返回的就是该行的物理地址。使用ROWID可以快速的定位表中的某一行。ROWID值可以唯一的标识表中的一行。由于ROWID返回的是该行的物理地址,因此使用ROWID可以显示行是如何存储的。

oracle教程 Oracle经典入门教程

代码演示:ROWID

oracle教程 Oracle经典入门教程

ROWID

AAAMgzAAEAAAAAgAAD

AAAMgzAAEAAAAAgAAF

AAAMgzAAEAAAAAgAAG

AAAMgzAAEAAAAAgAAH

AAAMgzAAEAAAAAgAAI

AAAMgzAAEAAAAAgAAM

6 rows selected ENAME JONES BLAKE CLARK SCOTT KING FORD

? ROWNUM

在查询的结果集中,ROWNUM为结果集中每一行标识一个行号,第一行返回1,第二行返回2,以此类推。[www.61k.com]通过ROWNUM伪列可以限制查询结果集中返回的行数。

案例4:查询出员工表中前5名员工的姓名,工作,工资。

代码演示:ROWNUM

SQL> SELECT ROWNUM,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=5; ROWNUM ENAME

1

2 3

4

5 JOB CLERK SALESMAN SALESMAN MANAGER SALESMAN SAL 800 1600 1250 2975 1250

oracle教程 Oracle经典入门教程

SMITH ALLEN WARD JONES MARTIN

oracle教程 Oracle经典入门教程

案例5:查询出工资最高的前5名员工的姓名、工资和工资。(www.61k.com)

案例分析

“工资最高的前5名”需要先降序排序,再取前5名,但是生成ROWNUM操作比排序要早,排序时已经连同ROWNUM一起排序了,因此不能直接在案例1的语句中直接加上Order by就行,而是需要对排序的结果重新做二次查询,产生新的ROWNUM才能作为查询的条件依据。

代码演示:ROWNUM应用 SQL> SELECT ROWNUM,T.* FROM ①

2 (SELECT ENAME,JOB,SAL

3 FROM EMP ORDER BY SAL DESC) T ②

4 WHERE ROWNUM<=5

5 /

ROWNUM ENAME

1

2

3

4

5 JOB SAL KING SCOTT FORD JONES BLAKE PRESIDENT 5000 ANALYST

oracle教程 Oracle经典入门教程

ANALYST MANAGER MANAGER 3000 3000 2975 2850

代码解析:

① T是子查询②的别名,这里的ROWNUM是第二次查询后的ROWNUM。

案例6:查询出表EMP中第5条到第10条之间的记录。

案例分析

这是分页的应用。在查询条件中,如果查询条件中ROWNUM大于某一正整数,则不返还任何结果。

代码演示:ROWNUM分页

2 (SELECT ROWNUM R,ENAME,JOB,SAL ①

3 FROM EMP WHERE ROWNUM<=10) ②

oracle教程 Oracle经典入门教程

4 WHERE R>5 ③

5 /

R

6

7

8

9

10 ENAME BLAKE CLARK SCOTT KING TURNER JOB MANAGER MANAGER ANALYST PRESIDENT SALESMAN SAL 2850 2450 3000 5000 1500

代码解析:

① 内部查询中得到ROWNUM 并且用别名R记录,供外层条件③使用。(www.61k.com)

② 内部查询的ROWNUM,与外出的ROWNUM列是平等的两列。

③ 使用的R是内层产生的ROWNUM,在外层看来,内层查询的ROWNUM是正常的一

列。

3. Oracle函数

Oracle SQL提供了用于执行特定操作的专用函数。这些函数大大增强了SQL语言的功能。函数可以接受零个或者多个输入参数,并返回一个输出结果。Oracle数据库中主要使用两种类型的函数:

1. 单行函数:对每一个函数应用在表的记录中时,只能输入一行结果,返回一个结果,

比如:MOD(x,y)返回x除以y的余数(x和y可以是两个整数,也可以是表中的整数列)。常用的单行函数有:

?

oracle教程 Oracle经典入门教程

字符函数:对字符串操作。

? 数字函数:对数字进行计算,返回一个数字。

? 转换函数:可以将一种数据类型转换为另外一种数据类型。

? 日期函数:对日期和时间进行处理。

2. 聚合函数:聚合函数同时可以对多行数据进行操作,并返回一个结果。比如SUM(x)

返回结果集中x列的总合。

? 字符函数

字符函数接受字符参数,这些参数可以是表中的列,也可以是一个字符串表达式。下表列出了常用的字符函数。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表1 字符函数

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表2 字符函数示例

? 数字函数

数字函数接受数字参数,参数可以来自表中的一列,也可以是一个数字表达式。[www.61k.com]

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表3 数字函数

说明:

1. ROUND(X[,Y]),四舍五入。[www.61k.com]

在缺省y时,默认y=0;比如:ROUND(3.56)=4。

y是正整数,就是四舍五入到小数点后y位。ROUND(5.654,2)=5.65。 y是负整数,四舍五入到小数点左边|y|位。ROUND(351.654,-2)=400。

2. TRUNC(x[,y]),直接截取,不四舍五入。

在缺省y时,默认y=0;比如:TRUNC (3.56)=3。

y是正整数,就是四舍五入到小数点后y位。TRUNC (5.654,2)=5.65。 y是负整数,四舍五入到小数点左边|y|位。TRUNC (351.654,-2)=300。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

? 日期函数

日期函数对日期进行运算。常用的日期函数有:

1. ADD_MONTHS(d,n),在某一个日期d上,加上指定的月数n,返回计算后的新日期。

d表示日期,n表示要加的月数。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图1 ADD_MONTHS函数示例

2. LAST_DAY(d),返回指定日期当月的最后一天。(www.61k.com)

oracle教程 Oracle经典入门教程

图2 LAST_DAY函数示例

3. ROUND(d[,fmt]),返回一个以fmt为格式的四舍五入日期值,d是日期,fmt是格式

模型。默认fmt为DDD,即月中的某一天。

? 如果fmt为“YEAR”则舍入到某年的1月1日,即前半年舍去,后半年作为下

一年。

? 如果fmt为“MONTH”则舍入到某月的1日,即前月舍去,后半月作为下一

月。

? 默认为“DDD”,即月中的某一天,最靠近的天,前半天舍去,后半天作为第

二天。

? 如果fmt为“DAY”则舍入到最近的周的周日,即上半周舍去,下半周作为下

一周周日。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图3 ROUND函数示例

与ROUND对应的函数时TRUNC(d[,fmt])对日期的操作,TRUNC与ROUND非常相似,只是不对日期进行舍入,直接截取到对应格式的第一天。(www.61k.com]

4. EXTRACT(fmt FROM d),提取日期中的特定部分。

fmt为:YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。其中YEAR、MONTH、DAY可以为DATE类型匹配,也可以与TIMESTAMP类型匹配;但是HOUR、MINUTE、SECOND必须与TIMESTAMP类型匹配。

HOUR匹配的结果中没有加上时区,因此在中国运行的结果小8小时。

oracle教程 Oracle经典入门教程

图4 EXTRACT函数示例

oracle教程 Oracle经典入门教程

? 转换函数

转换函数将值从一种数据类型转换为另外一种数据类型。[www.61k.com]常用的转换函数有:

1. TO_CHAR(d|n[,fmt])

把日期和数字转换为制定格式的字符串。fmt是格式化字符串,日期的格式化字符串前面已经学习过。

代码演示:TO_CHAR对日期的处理

SQL> SELECT TO_CHAR(SYSDATE,'YYYY"年"MM"月"DD"日" HH24:MI:SS') "date" ① 2 FROM DUAL;

date

-----------------------

2009年08月11日 12:06:00

代码解析:

① 在格式化字符串中,使用双引号对非格式化字符进行引用。

针对数字的格式化,格式化字符有:

oracle教程 Oracle经典入门教程

表4 数字格式化字符

代码演示:TO_CHAR对数字的处理

SQL> SELECT TO_CHAR(-123123.45,'L9.9EEEEPR') "date"

2 FROM DUAL

3 /

date

--------------------

oracle教程 Oracle经典入门教程

<¥1.2E+05>

2. TO_DATE(x [,fmt])

把一个字符串以fmt格式转换为一个日期类型,前面已经学习过。(www.61k.com)

3. TO_NUMBER(x[,fmt])

把一个字符串以fmt格式转换为一个数字。fmt格式字符参考表3。

代码演示:TO_NUM函数

SQL> SELECT TO_NUMBER('-$12,345.67','$99,999.99') "NUM"

2 FROM DUAL

3 /

NUM

---------------

-12345.67

? 其他单行函数

1. NVL(x,value)

如果x为空,返回value,否则返回x。

代码演示:NVL函数

SQL> SELECT ENAME,JOB,SAL,NVL(COMM,100) FROM EMP WHERE SAL<2000; ENAME

SMITH

ALLEN

WARD

MARTIN

TURNER

ADAMS

JAMES

7 rows selected JOB CLERK SALESMAN SALESMAN SALESMAN SALESMAN CLERK CLERK SAL 800 1600 1250 1250 1500 1100 950 NVL(COMM,100) 100 300 500 1400 50 100 100 案例7:对工资是2000元以下的员工,如果没有发奖金,每人奖金100元。

oracle教程 Oracle经典入门教程

2. NVL2(x,value1,value2)

如果x非空,返回value1,否则返回value2。(www.61k.com)

案例8:对EMP表中工资为2000元以下的员工,如果没有奖金,则奖金为200元,如果有奖金,则在原来的奖金基础上加100元。

代码演示:NVL2函数

SQL> SELECT ENAME,JOB,SAL,NVL2(COMM,comm+100,200) "comm"

2 FROM EMP WHERE SAL<2000;

ENAME

SMITH

ALLEN

WARD

MARTIN

TURNER

ADAMS

JAMES

MILLER JOB CLERK SALESMAN SALESMAN SALESMAN SALESMAN CLERK CLERK CLERK SAL 800 1600 1250 1250 1500 1100 950 1300 comm 200 400 600 1500 150 200 200 200 8 rows selected

? 聚合函数

聚合函数同时对一组数据进行操作,返回一行结果,比如计算一组数据的总和,平均值等。

oracle教程 Oracle经典入门教程

表 5 聚合函数

案例9:求本月所有员工的基本工资总和。

代码演示:SUM函数

oracle教程 Oracle经典入门教程

SQL> select sum(sal) from emp;

SUM(SAL)

----------------

29025

案例10:求不同部门的平均工资。(www.61k.com]

代码演示:AVG函数下的分组查询

SQL> SELECT DEPTNO,AVG(SAL) FROM EMP GROUP BY DEPTNO;

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

DEPTNO AVG(SAL)

--------- ----------

30 1566.66666

20 2175

10 2916.66666

oracle教程 Oracle经典入门教程

4. 本章总结

? Oracle常用函数有字符相关的函数、数字相关的函数、日期相关的函数、转换函数

等。(www.61k.com]

? EXTRACT函数能够获取日期中的某个字段的值。

? TO_CHAR函数能够把数字和日期转换成固定的字符串格式。TO_DATE 函数能够把

固定格式的字符串转换为日期类型。

? 子查询中有返回单行的子查询和返回多行的子查询。

? Oracle中存在ROWID、ROWNUM等伪列。

oracle教程 Oracle经典入门教程

5. 本章练习

1. 描述TO_CHAR和TO_DATE函数的用法。[www.61k.com]

2. 描述EXTRACT函数的用法。

3. 你知道有哪些关于日期函数的用法?

oracle教程 Oracle经典入门教程

章节知识结构图

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

[www.61k.com)

oracle教程 Oracle经典入门教程

第4章

表空间、数据库对象

主要内容 ? 同义词概念

? 序列的应用

? 视图的概念

? 索引的概念

? 表空间的概念

oracle教程 Oracle经典入门教程

1. Oracle数据库对象

数据库对象是数据库的组成部分,常常用CREATE命令进行创建,可以使用ALTER命令修改,用DROP执行删除操作。(www.61k.com]前面已经接触过的数据库对象有表、用户等。

今天将学习更多的Oracle数据库对象:

? 同义词:就是给数据库对象一个别名。

? 序列:Oracle中实现增长的对象。

? 视图:预定义的查询,作为表一样的查询使用,是一张虚拟表。

? 索引:对数据库表中的某些列进行排序,便于提高查询效率。

2. 同义词

同义词(Synonym)是数据库对象的一个别名,Oracle可以为表、视图、序列、过程、函数、程序包等指定一个别名。同义词有两种类型:

? 私有同义词:拥有CREATE SYNONYM权限的用户(包括非管理员用户)即可创建私

有同义词,创建的私有同义词只能由当前用户使用。

? 公有同义词:系统管理员可以创建公有同义词,公有同义词可以被所有用户访问。

语法结构:同义词

CREATE [OR REPLACE] [PUBLIC] SYSNONYM [schema.]synonym_name FOR [schema.]object_name 创建同义词的语法是:

语法解析:

① CREATE [OR REPLACE:]表示在创建同义词时,如果该同义词已经存在,那么就用新创建的同义词代替旧同义词。

② PULBIC:创建公有同义词时使用的关键字,一般情况下不需要创建公有同义词。 ③ Oracle中一个用户可以创建表、视图等多种数据库对象,一个用户和该用户下的所有数据库对象的集合称为Schema(中文称为模式或者方案),用户名就是Schema名。一个数据库对象的全称是:用户名.对象名,即schema.object_name。

如果一个用户有权限访问其他用户对象时,就可以使用全称来访问。比如:

oracle教程 Oracle经典入门教程

代码演示:System用户访问Scott用户的Emp表

SQL> conn system/manager@orcl;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

Connected as system

SQL> SELECT ENAME,JOB,SAL FROM SCOTT.EMP WHERE SAL>2000; ①

ENAME

JONES

BLAKE

CLARK

SCOTT

KING

FORD JOB MANAGER MANAGER MANAGER ANALYST PRESIDENT ANALYST SAL 2975 2850 2450 3000 5000 3000

6 rows selected

代码解析:

① 管理员用户可以访问任何用户的数据库对象,SYSTEM用户访问SCOTT用户的EMP

表时,必须使用SCOTT.EMP。(www.61k.com)

案例1:创建一个用户XiaoMei,该用户拥有CONNECT角色和RESOURCE角色。为SCOTT用户的EMP表创建同义词,并通过同义词访问该EMP表。

代码演示:创建同义词并访问

SQL> CONN system/manager@orcl;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

Connected as system

SQL> CREATE USER XiaoMei IDENTIFIED BY XiaoMei; ①

User created

SQL> GRANT CONNECT TO XiaoMei;

Grant succeeded

SQL> GRANT RESOURCE TO XiaoMei;

Grant succeeded

SQL> GRANT CREATE SYNONYM TO XiaoMei; Grant succeeded

oracle教程 Oracle经典入门教程

SQL> CONN XiaoMei/XiaoMei@ORCL;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

Connected as XiaoMei

SQL> CREATE SYNONYM MyEmp FOR SCOTT.EMP; ②

Synonym created

SQL> SELECT * FROM MYEMP; ③

SELECT * FROM MYEMP

ORA-00942: 表或视图不存在

SQL> CONNECT SCOTT/tiger@ORCL

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

Connected as SCOTT

SQL> GRANT ALL ON EMP TO XiaoMei; ④

Grant succeeded

SQL> CONNECT XiaoMei/XiaoMei@ORCL;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0

Connected as XiaoMei

SQL> SELECT ENAME,JOB,SAL FROM MyEmp WHERE SAL>2000; ⑤

ENAME

JONES

BLAKE

CLARK

SCOTT

KING

FORD JOB MANAGER MANAGER MANAGER ANALYST PRESIDENT ANALYST SAL 2975 2850 2450 3000 5000 3000

6 rows selected

代码解析:

① 在管理员用户下创建用户XiaoMei,对用户XiaoMei授予CONNECT和RESOURCE角

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

色。[www.61k.com)为了XiaoMei能够创建序列,必须授予系统权限:CREATE SYNONYM。

② 在XiaoMei用户下,为SCOTT.EMP创建私有同义词MyEmp,同义词MyEmp只能在

XiaoMei用户下使用。访问MyEmp就是访问SCOTT.EMP对象。

oracle教程 Oracle经典入门教程

③ 访问MyEmp对象出错:对象不存在。[www.61k.com]因为XiaoMei如果访问MyEmp,就相当于访

问SCOTT.EMP对象,那么SCOTT用户必须对XiaoMei授予相应的权限。

④ SCOTT用户下,把EMP表的所有权限(增删改查)授予XiaoMei。

⑤ 对MyEmp执行查询操作。MyEmp就可以像在本地的表一样使用。

删除同义词使用的语法是:

语法结构:删除同义词

DROP [PUBLIC] SYNONYM [schema.]sysnonym_name

语法解析:

① PUBLIC:删除公共同义词。

② 同义词的删除只能被拥有同义词对象的用户或者管理员删除。

③ 此命令只能删除同义词,不能删除同义词下的源对象。

3. 序列

序列(Sequence)是用来生成连续的整数数据的对象。序列常常用来作为主键中增长列,序列中的可以升序生成,也可以降序生成。创建序列的语法是:

语法结构:创建序列

CREATE SEQUENCE sequence_name

[START WITH num]

[INCREMENT BY increment]

[MAXVALUE num|NOMAXVALUE]

[MINVALUE num|NOMINVALUE]

[CYCLE|NOCYCLE] [CACHE num|NOCACHE]

语法解析:

① START WITH:从某一个整数开始,升序默认值是1,降序默认值是-1。

② INCREMENT BY:增长数。如果是正数则升序生成,如果是负数则降序生成。升序默

认值是1,降序默认值是-1。

③ MAXVALUE:指最大值。

④ NOMAXVALUE:这是最大值的默认选项,升序的最大值是:1027,降序默认值是-1。 ⑤ MINVALUE:指最小值。

oracle教程 Oracle经典入门教程

⑥ NOMINVALUE:这是默认值选项,升序默认值是1,降序默认值是-1026。(www.61k.com]

⑦ CYCLE:表示如果升序达到最大值后,从最小值重新开始;如果是降序序列,达到最

小值后,从最大值重新开始。

⑧ NOCYCLE:表示不重新开始,序列升序达到最大值、降序达到最小值后就报错。默

认NOCYCLE。

⑨ CACHE:使用CACHE选项时,该序列会根据序列规则预生成一组序列号。保留在内

存中,当使用下一个序列号时,可以更快的响应。当内存中的序列号用完时,系统再生成一组新的序列号,并保存在缓存中,这样可以提高生成序列号的效率。Oracle默认会生产20个序列号。

⑩ NOCACHE:不预先在内存中生成序列号。

案例2:创建一个从1开始,默认最大值,每次增长1的序列,要求NOCYCLE,缓存中有30个预先分配好的序列号。

代码演示:生成序列号

SQL> CREATE SEQUENCE MYSEQ

2 MINVALUE 1

3 START WITH 1

4 NOMAXVALUE

5 INCREMENT BY 1

6 NOCYCLE

7 CACHE 30

8 /

Sequence created

序列创建之后,可以通过序列对象的CURRVAL和NEXTVAL两个“伪列”分别访问该序列的当前值和下一个值。

代码演示:序列使用

SQL> SELECT MYSEQ.NEXTVAL FROM DUAL;

NEXTVAL

----------

1

SQL> SELECT MYSEQ.NEXTVAL FROM DUAL; NEXTVAL

oracle教程 Oracle经典入门教程

----------

2

SQL> SELECT MYSEQ.CURRVAL FROM DUAL;

CURRVAL

----------

2

使用ALTER SEQUENCE可以修改序列,在修改序列时有如下限制:

1. 不能修改序列的初始值。(www.61k.com)

2. 最小值不能大于当前值。

3. 最大值不能小于当前值。

使用DROP SEQUENCE命令可以删除一个序列对象。

代码演示:序列修改和删除

SQL> ALTER SEQUENCE MYSEQ

2 MAXVALUE 10000

3 MINVALUE -300

4 /

SEQUENCE ALTERED

SQL> DROP SEQUENCE MYSEQ; SEQUENCE DROPPED

4. 视图

视图(View)实际上是一张或者多张表上的预定义查询,这些表称为基表。从视图中查询信息与从表中查询信息的方法完全相同。只需要简单的SELECT…FROM即可。

视图具有以下优点:

1. 可以限制用户只能通过视图检索数据。这样就可以对最终用户屏蔽建表时底层的基

表。

2. 可以将复杂的查询保存为视图。可以对最终用户屏蔽一定的复杂性。

3. 限制某个视图只能访问基表中的部分列或者部分行的特定数据。这样可以实现一定

的安全性。

4. 从多张基表中按一定的业务逻辑抽出用户关心的部分,形成一张虚拟表。

oracle教程 Oracle经典入门教程

语法结构:创建视图

CREATE [OR REPLACE] [{FORCE|NOFORCE}] VIEW view_name

AS

SELECT查询

[WITH READ ONLY CONSTRAINT]

语法解析:

1. OR REPLACE:如果视图已经存在,则替换旧视图。[www.61k.com]

2. FORCE:即使基表不存在,也可以创建该视图,但是该视图不能正常使用,当基表

创建成功后,视图才能正常使用。

3. NOFORCE:如果基表不存在,无法创建视图,该项是默认选项。

4. WITH READ ONLY:默认可以通过视图对基表执行增删改操作,但是有很多在基表上

的限制(比如:基表中某列不能为空,但是该列没有出现在视图中,则不能通过视图执行insert操作),WITH READ ONLY说明视图是只读视图,不能通过该视图进行增删改操作。现实开发中,基本上不通过视图对表中的数据进行增删改操作。

案例3:基于EMP表和DEPT表创建视图

代码演示:视图

SQL> CREATE OR REPLACE VIEW EMPDETAIL

2 AS

3 SELECT EMPNO,ENAME,JOB,HIREDATE,EMP.DEPTNO,DNAME

4 FROM EMP JOIN DEPT ON EMP.DEPTNO=DEPT.DEPTNO

5 WITH READ ONLY

6 /

VIEW CREATED

SQL> SELECT * FROM EMPDETAIL; ①

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

EMPNO ENAME

7369

7499

7521

7566

7654 SMITH ALLEN WARD JONES MARTIN JOB CLERK SALESMAN SALESMAN MANAGER SALESMAN HIREDATE DEPTNO DNAME RESEARCH SALES SALES RESEARCH SALES 17-12月-80 20 20-2月 -81 22-2月 -81 02-4月 -81 28-9月 -81 30 30 20 30

oracle教程 Oracle经典入门教程

7698 7782 7788 7839 7844 7876 7900 7902 7934

BLAKE CLARK SCOTT KING TURNER ADAMS JAMES FORD MILLER

MANAGER MANAGER ANALYST

01-5月 -81 09-6月 -81 19-4月 -87

30 10 20

SALES ACCOUNTING RESEARCH ACCOUNTING SALES RESEARCH SALES RESEARCH ACCOUNTING

PRESIDENT 17-11月-81 10 SALESMAN CLERK CLERK ANALYST CLERK

08-9月 -81 23-5月 -87

30 20

03-12月-81 30 03-12月-81 20 23-1月 -82

10

14 ROWS SELECTED

代码解析:

① 对视图可以像表一样进行查询。[www.61k.com]该视图中隐藏了员工的工资。

删除视图可以使用“DROP VIEW 视图名称”,删除视图不会影响基表的数据。

5. 索引

当我们在某本书中查找特定的章节内容时,可以先从书的目录着手,找到该章节所在的页码,然后快速的定位到该页。这种做法的前提是页面编号是有序的。如果页码无序,就只能从第一页开始,一页页的查找了。

数据库中索引(Index)的概念与目录的概念非常类似。如果某列出现在查询的条件中,而该列的数据是无序的,查询时只能从第一行开始一行一行的匹配。创建索引就是对某些特定列中的数据排序,生成独立的索引表。在某列上创建索引后,如果该列出现在查询条件中,Oracle会自动的引用该索引,先从索引表中查询出符合条件记录的ROWID,由于ROWID是记录的物理地址,因此可以根据ROWID快速的定位到具体的记录,表中的数据非常多时,引用索引带来的查询效率非常可观。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

Oracle数据库会为表的主键和包含唯一约束的列自动创建索引。[www.61k.com)索引可以提高查询的效率,但是在数据增删改时需要更新索引,因此索引对增删改时会有负面影响。

语法结构:创建索引

CREATE [UNIQUE] INDEX index_name ON

table_name(column_name[,column_name…])

语法解析:

1. UNIQUE:指定索引列上的值必须是唯一的。称为唯一索引。

2. index_name:指定索引名。

3. tabl_name:指定要为哪个表创建索引。

4. column_name:指定要对哪个列创建索引。我们也可以对多列创建索引;这种索引

称为组合索引。

案例4:为EMP表的ENAME列创建创建唯一索引,为EMP表的工资列创建普通索引,把JOB列先变为小写再创建索引。

代码演示:创建索引

SQL> CREATE UNIQUE INDEX UQ_ENAME_IDX ON EMP(ENAME); ①

Index created

SQL> CREATE INDEX IDX_SAL ON EMP(SAL); ②

Index created

SQL> CREATE INDEX IDX_JOB_LOWER ON EMP(LOWER(JOB)); ③ Index created

代码解析:

① 为SCOTT.EMP表的ENAME列创建唯一索引。

② 为SCOTT.EMP表的SAL列创建索引。

③ 在查询中可能经常使用job的小写作为条件的表达式,因此创建索引时,可以先对

JOB列中的所有值转换为小写后创建索引,而这时需要使用lower函数,这种索引称为基于函数的索引。

在select语句查询时,Oracle系统会自动为查询条件上的列应用索引。索引就是对某一列进行排序,因此在索引列上,重复值越少,索引的效果越明显。

Oracle可以为一些列值重复非常多且值有限的列(比如性别列)上创建位图索引。关于Oracle更多的索引类型(比如反向键索引等),请参考Oracle官方文档。

oracle教程 Oracle经典入门教程

6. 表空间

在数据库系统中,存储空间是较为重要的资源,合理利用空间,不但能节省空间,还可以提高系统的效率和工作性能。[www.61k.com]Oracle可以存放海量数据,所有数据都在数据文件中存储。而数据文件大小受操作系统限制,并且过大的数据文件对数据的存取性能影响非常大。同时Oracle是跨平台的数据库,Oracle数据可以轻松的在不同平台上移植,那么如何才能提供统一存取格式的大容量呢?Oracle采用表空间来解决。

表空间只是一个逻辑概念,若干操作系统文件(文件可以不是很大)可以组成一个表空间。表空间统一管理空间中的数据文件,一个数据文件只能属于一个表空间。一个数据库空间由若干个表空间组成。如图所示:

oracle教程 Oracle经典入门教程

图1 数据空间、表空间和数据文件

Oracle中所有的数据(包括系统数据),全部保存在表空间中,常见的表空间有:

? 系统表空间:存放系统数据,系统表空间在数据库创建时创建。表空间名称为

SYSTEM。存放数据字典和视图以及数据库结构等重要系统数据信息,在运行时如果SYSTEM空间不足,对数据库影响会比较大,虽然在系统运行过程中可以通过命令扩充空间,但还是会影响数据库的性能,因此有必要在创建数据库时适当的把数据文件设置大一些。

? TMEP表空间:临时表空间,安装数据库时创建,可以在运行时通过命令增大临时

表空间。临时表空间的重要作用是数据排序。比如当用户执行了诸如Order by等命令后,服务器需要对所选取数据进行排序,如果数据很大,内存的排序区可能装不下太大数据,就需要把一些中间的排序结果写在硬盘的临时表空间中。

? 用户表自定义空间:用户可以通过CREATE TABLESPACE命令创建表空间。

创建表空间需要考虑数据库对分区(Extent,一个Oracle分区是数据库文件中一段连续的空间,Oracle分区是Oracle管理中最小的单位)的管理,比如当一个表创建后先申请一个

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

oracle教程 Oracle经典入门教程

分区,在Insert执行过程中,如果分区数据已满,需要重新申请另外的分区。[www.61k.com)如果一个数据库中的分区大小不一,创建表空间时需要考虑一系列问题。因此在Oracle8i之后,创建表空间都推荐使用“本地管理表空间”,这种表空间中的分区是一个固定大小的值,创建表空间的语法是:

语法结构:创建表空间

CREATE TABLESPACE 空间名称

DATAFILE '文件名1' SIZE 数字M

[,'文件名2' SIZE 数字….]

EXTENT MANAGEMENT LOCAL

UNIFORM SIZE 数字M

语法解析:

1. 文件名包括完整路径和文件名,每个数据文件定义了文件的初始大小,初始大小一

般以“M”为单位。一个表空间中可以有多个数据文件。

2. EXTENT MANAGEMENT LOCAL指明表空间类型是:本地管理表空间。本地管理表空

间要求Oracle中的数据分区(Extent)大小统一。

3. UNIFORM SIZE:指定每个分区的统一大小。

案例5:创建一个表空间,包含两个数据文件大小分别是10MB,5MB,要求extent的大小统一为1M。

代码演示:创建表空间

SQL> CREATE TABLESPACE MYSPACE

2 DATAFILE 'D:/A.ORA' SIZE 10M,

3 'D:/B.ORA' SIZE 5M

4 EXTENT MANAGEMENT LOCAL

5 UNIFORM SIZE 1M

6 /

Tablespace created

必须是管理员用户才能创建表空间,当表空间的空间不足时可以使用ALTER TABLESPACE命令向表空间中追加数据文件扩充表空间。

代码演示:扩充表空间

oracle教程 Oracle经典入门教程

SQL> ALTER TABLESPACE MYSPACE

2 ADD DATAFILE 'D:/C.ORA' SIZE 10M

3 /

Tablespace altered

代码演示:为某一用户指定默认表空间

SQL> CREATE USER ACONG IDENTIFIED BY ACONG 2 DEFAULT TABLESPACE MYSPACE

3 /

User created 表空间可以在不使用时删除,使用DROP TABLESPACE命令。(www.61k.com] 数据库的所有数据全部在某一表空间中存放,在创建用户时,可以为用户指定某一表空间,那么该用户下的所有数据库对象(比如表)默认都存储在该空间中。

代码演示:为表指定表空间

SQL> CREATE TABLE SCORES

2 (

3 ID NUMBER ,

4 TERM VARCHAR2(2),

5 STUID VARCHAR2(7) NOT NULL, 6 EXAMNO VARCHAR2(7) NOT NULL,

7 WRITTENSCORE NUMBER(4,1) NOT NULL, 8 LABSCORE NUMBER(4,1) NOT NULL 9 )

10 TABLESPACE MYSPACE

11 /

Table created 在创建表时,表中数据存放在用户的默认表空间中,也可以通过tablespace子句为表指定表中数据存放在其他表空间中。

创建索引时也可以为索引指定表空间。

oracle教程 Oracle经典入门教程

代码演示:为索引指定表空间

SQL> CREATE INDEX UQ_ID ON SCORES(ID) 2 TABLESPACE MYSPACE;

Index created

表和索引一旦创建,表空间无法修改。[www.61k.com]

oracle教程 Oracle经典入门教程

7. 本章总结

? Oracle数据库对象都是使用CREATE命令创建的。(www.61k.com)

? 同义词就是数据库对象的一个别名。同义词的类型有公有同义词和私有同义词。只

有管理员可以创建共有同义词。创建同义词的命令是:CREATE SYNONYM。

? 序列能够产生一个连续不重复的整数。经常作为数据库的主键生成器。创建序列的

命令是CREATE SEQUENCE。

? 序列的访问使用两个“伪列”,CURRVAL表示序列的当前值,NEXTVAL表示序列的

下一个值。

? 视图就是一个预处理的查询语句,可以从若干表中过滤数据。

? 索引就是在查询中经常使用的列进行排序。常见的索引有:普通索引、唯一序列、

组合索引以及基于函数的索引。此外还有位图索引、反向键索引等。

? 表空间是数据库的一个逻辑概念,表空间由若干个数据文件组成。为数据库对象和

数据提供统一的空间管理。

oracle教程 Oracle经典入门教程

8. 本章练习

1. 产生一个用于DEPT表的主键值的序列,序列起始值是100,最大值是500,增长步

长是10。[www.61k.com)

2. 用序列产生DEPT表的主键,向DEPT表中插入3条记录。

3. 为DEPT表创建一个同义词。

4. 创建一个视图包括EMP表的EMPNO,ENAME,JOB,部门表的DNAME列,只能包含

销售部的记录。

5. 为EMP表的ENAME列创建唯一索引。

6. 为EMP表的SAL列创建一个普通索引。

7. 以学期和学生姓名为名称比如(S2XiaoMei)创建一个表空间,该表空间是以学生姓

名为用户的默认表空间。

oracle教程 Oracle经典入门教程

章节知识结构图

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

(www.61k.com)

oracle教程 Oracle经典入门教程

第5章

PL/SQL程序设计

主要内容 ? PL/SQL数据类型

? PL/SQL条件和循环控制

? 动态执行SQL

? PL/SQL中的异常处理

oracle教程 Oracle经典入门教程

1. PL/SQL简介

从第一学期到现在,在数据库上一直使用单一的SQL语句进行数据操作,没有流程控制,无法开发复杂的应用。[www.61k.com)Oracle PL/SQL语言(Procedural Language/SQL)是结合了结构化查询与Oracle自身过程控制为一体的强大语言,PL/SQL不但支持更多的数据类型,拥有自身的变量声明、赋值语句,而且还有条件、循环等流程控制语句。过程控制结构与SQL数据处理能力无缝的结合形成了强大的编程语言,可以创建过程和函数以及程序包。

PL/SQL是一种块结构的语言,它将一组语句放在一个块中,一次性发送给服务器,PL/SQL引擎分析收到PL/SQL语句块中的内容,把其中的过程控制语句由PL/SQL引擎自身去执行,把PL/SQL块中的SQL语句交给服务器的SQL语句执行器执行。如图所示:

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

oracle教程 Oracle经典入门教程

图1 PL/SQL体系结构

? 支持SQL

SQL是访问数据库的标准语言,通过SQL命令,用户可以操纵数据库中的数据。PL/SQL支持所有的SQL数据操纵命令、游标控制命令、事务控制命令、SQL函数、运算符和伪列。同时PL/SQL和SQL语言紧密集成,PL/SQL支持所有的SQL数据类型和NULL值。

? 支持面向对象编程

PL/SQL支持面向对象的编程,在PL/SQL中可以创建类型,可以对类型进行继承,可以在子程序中重载方法等。

? 更好的性能 PL/SQL块发送给服务器后,先被编译然后执行,对于有名称的PL/SQL块(如子程序)可以单独编译,永久的存储在数据库中,随时准备执行。PL/SQL的优点还有:

oracle教程 Oracle经典入门教程

SQL是非过程语言,只能一条一条执行,而PL/SQL把一个PL/SQL块统一进行编译后执行,同时还可以把编译好的PL/SQL块存储起来,以备重用,减少了应用程序和服务器之间的通信时间,PL/SQL是快速而高效的。[www.61k.com]

? 可移植性

使用PL/SQL编写的应用程序,可以移植到任何操作系统平台上的Oracle服务器,同时还可以编写可移植程序库,在不同环境中重用。

? 安全性

可以通过存储过程对客户机和服务器之间的应用程序逻辑进行分隔,这样可以限制对Oracle数据库的访问,数据库还可以授权和撤销其他用户访问的能力。

2. PL/SQL块

PL/SQL是一种块结构的语言,一个PL/SQL程序包含了一个或者多个逻辑块,逻辑块中可以声明变量,变量在使用之前必须先声明。除了正常的执行程序外,PL/SQL还提供了专门的异常处理部分进行异常处理。每个逻辑块分为三个部分,语法是:

语法结构:PL/SQL块的语法

[DECLARE

--declaration statements] ①

BEGIN

--executable statements ②

[EXCEPTION

--exception statements] ③ END;

语法解析:

① 声明部分:声明部分包含了变量和常量的定义。这个部分由关键字DECLARE开始,

如果不声明变量或者常量,可以省略这部分。

② 执行部分:执行部分是 PL/SQL块的指令部分,由关键字BEGIN开始,关键字END

结尾。所有的可执行PL/SQL语句都放在这一部分,该部分执行命令并操作变量。其他的PL/SQL块可以作为子块嵌套在该部分。PL/SQL块的执行部分是必选的。注意END关键字后面用分号结尾。

oracle教程 Oracle经典入门教程

③ 异常处理部分:该部分是可选的,该部分用EXCEPTION关键字把可执行部分分成两

个小部分,之前的程序是正常运行的程序,一旦出现异常就跳转到异常部分执行。[www.61k.com)

PL/SQL是一种编程语言,与Java和C#一样,除了有自身独有的数据类型、变量声明和赋值以及流程控制语句外,PL/SQL还有自身的语言特性:

PL/SQL对大小写不敏感,为了良好的程序风格,开发团队都会选择一个合适的编码标准。比如有的团队规定:关键字全部大些,其余的部分小写。

PL/SQL块中的每一条语句都必须以分号结束,SQL语句可以是多行的,但分号表示该语句结束。一行中可以有多条SQL语句,他们之间以分号分隔,但是不推荐一行中写多条语句。

PL/SQL中的特殊符号说明:

oracle教程 Oracle经典入门教程

表1 PL/SQL中的特殊符号和运算符

? 变量声明

PL/SQL支持SQL中的数据类型,PL/SQL中正常支持NUMBER,VARCHAR2,DATE等Oracle SQL数据类型。声明变量必须指明变量的数据类型,也可以声明变量时对变量初始化,变量声明必须在声明部分。声明变量的语法是:

语法格式:声明变量

变量名 数据类型[ :=初始值]

oracle教程 Oracle经典入门教程

语法解析:

数据类型如果需要长度,可以用括号指明长度,比如:varchar2(20)。(www.61k.com]

代码演示:声明变量

SQL> DECLARE

2 sname VARCHAR2(20) :='jerry'; ①

3 BEGIN

4 sname:=sname||' and tom'; ②

5 dbms_output.put_line(sname); ③

6 END;

7 /jerry PL/SQL procedure successfully completed

代码解析:

① 声明一个变量sname,初始化值是“jerry”。字符串用单引号,如果字符串中出现单

引号可以使用两个单引号(’’)来表示,即单引号同时也具有转义的作用。 ② 对变量sname重新赋值,赋值运算符是“:=”。

③ dbms_output.put_line是输出语句,可以把一个变量的值输出,在SQL*Plus中输出

数据时,可能没有结果显示,可以使用命令:set serveroutput on设置输出到SQL*Plus控制台上。

对变量赋值还可以使用SELECT…INTO 语句从数据库中查询数据对变量进行赋值。但是查询的结果只能是一行记录,不能是零行或者多行记录。

代码演示:变量赋值

SQL> DECLARE

2 sname VARCHAR2(20) DEFAULT 'jerry'; ①

3 BEGIN

4 SELECT ename INTO sname FROM emp WHERE empno=7934; ② 5 dbms_output.put_line(sname);

6 END;

7 /

MILLER PL/SQL procedure successfully completed

代码解析:

① 变量初始化时,可以使用DEFAULT关键字对变量进行初始化。

oracle教程 Oracle经典入门教程

② 使用select…into语句对变量sname赋值,要求查询的结果必须是一行,不能是多

行或者没有记录。(www.61k.com]

? 声明常量

常量在声明时赋予初值,并且在运行时不允许重新赋值。使用CONSTANT关键字声明常量。

代码演示:声明常量

SQL> DECLARE

2 pi CONSTANT number :=3.14; --圆周率长值 ①

3 r number DEFAULT 3; --圆的半径默认值3 ②

4 area number; --面积。

5 BEGIN

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

6 area:=pi*r*r; --计算面积

7 dbms_output.put_line(area); --输出圆的面积

8 END;

9 /

28.26

PL/SQL procedure successfully completed

代码解析:

① 声明常量时使用关键字CONSTANT,常量初值可以使用赋值运算符(:=)赋值,也

可以使用DEFAULT关键字赋值。

在SQL*Plus中还可以声明Session(会话,也就是一个客户端从连接到退出的过程称为当前用户的会话。)全局级变量,该变量在整个会话过程中均起作用,类似的这种变量称为宿主变量。宿主变量在PL/SQL引用时要用“:变量名”引用。

代码演示:宿主常量

SQL> var emp_name varchar(30); ①

SQL> BEGIN

2 SELECT ename INTO :emp_name FROM emp WHERE empno=7499; ②

3 END;

oracle教程 Oracle经典入门教程

4 /

PL/SQL procedure successfully completed

emp_name

---------

ALLEN

SQL> print emp_name; ③

emp_name

--------- ALLEN

代码解析:

① 可以使用var声明宿主变量。(www.61k.com)

② PL/SQL中访问宿主变量时要在变量前加“:”。

③ 在SQL*Plus中,使用print可以输出变量中的结果。

3. PL/SQL数据类型

前面在建表时,学习过Oracle SQL的数据类型,PL/SQL不但支持这些数据类型,还具备自身的数据类型。PL/SQL的数据类型包括标量数据类型,引用数据类型和存储文本、图像、视频、声音等非结构化的大数据类型(LOB数据类型)等。下面列举一些常用的类型。

? 标量数据类型

标量数据类型的变量只有一个值,且内部没有分量。标量数据类型包括数字型,字符型,日期型和布尔型。这些类型有的是Oracle SQL中定义的数据类型,有的是PL/SQL自身附加的数据类型。字符型和数字型又有子类型,子类型只与限定的范围有关,比如NUMBER类型可以表示整数,也可以表示小数,而其子类型POSITIVE只表示正整数。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表2 PL/SQL中标量数据类型。(www.61k.com)

? 属性数据类型

当声明一个变量的值是数据库中的一行或者是数据库中某列时,可以直接使用属性类型来声明。Oracle中存在两种属性类型:%TYPE和%ROWTYPE。

? % ROWTYPE

引用数据库表中的一行作为数据类型,即RECORD类型(记录类型),是PL/SQL附加的数据类型。表示一条记录,就相当于C#中的一个对象。可以使用“.”来访问记录中的属性。

代码演示:

SQL> DECLARE

2 myemp EMP%ROWTYPE; ①

3 BEGIN

4 SELECT * INTO myemp FROM emp WHERE empno=7934; ②

5 dbms_output.put_line(myemp.ename); ③

6 END;

7 /

MILLER

oracle教程 Oracle经典入门教程

PL/SQL procedure successfully completed

代码解析:

① 声明一个myemp对象,该对象表示EMP表中的一行。[www.61k.com)

② 从EMP表中查询一条记录放入myemp对象中。

③ 访问该对象的属性可以使用“.”。

? %TYPE

引用某个变量或者数据库的列的类型作为某变量的数据类型。

代码演示:%TYPE应用

SQL> DECLARE

2 sal emp.sal%TYPE; ①

3 mysal number(4):=3000;

4 totalsal mysal%TYPE; ②

5 BEGIN

6 SELECT SAL INTO sal FROM emp WHERE empno=7934;

7 totalsal:=sal+mysal;

8 dbms_output.put_line(totalsal);

9 END;

10 /

4300 PL/SQL procedure successfully completed

代码解析:

① 定义变量sal为emp表中sal列的类型。

② 定义totalsal是变量mysal的类型。

%TYPE可以引用表中的某列作的类型为变量的数据类型,也可以引用某变量的类型作为新变量的数据类型。

4. PL/SQL条件控制和循环控制

PL/SQL程序可通过条件或循环结构来控制命令执行的流程。PL/SQL提供了丰富的流程控制语句,与C#一样也有三种控制结构:

? 顺序结构

? 条件结构

oracle教程 Oracle经典入门教程

? 循环结构

? 条件控制

C#中的条件控制使用关键字if和switch。[www.61k.com)PL/SQL中关于条件控制的关键字有IF-THEN、IF-THEN-ELSE、IF-THEN-ELSIF和多分枝条件CASE。

? IF-THEN

该结构先判断一个条件是否为TRUE,条件成立则执行对应的语句块,与C#中的if语句很相似,具体语法是:

oracle教程 Oracle经典入门教程

说明:

① 用IF关键字开始,END IF关键字结束,注意END IF后面有一个分号。

② 条件部分可以不使用括号,但是必须以关键字THEN来标识条件结束,如果条件成

立,则执行THEN后到对应END IF之间的语句块内容。如果条件不成立,则不执行条件语句块的内容。

③ C#结构用一对大括号来包含条件结构体的内容。PL/SQL中关键字THEN到END IF之

间的内容是条件结构体内容。

④ 条件可以使用关系运算符合逻辑运算符。

案例1:查询JAMES的工资,如果大于900元,则发奖金800元。

代码演示:IF-THEN应用

DECLARE

newSal emp.sal % TYPE;

BEGIN

SELECT sal INTO newSal FROM emp

WHERE ename='JAMES';

IF newSal>900 THEN ① 表3 PL/SQL中条件语法

oracle教程 Oracle经典入门教程

UPDATE emp

SET comm=800

WHERE ename='JAMES';

END IF;

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

COMMIT ; ② END;

代码解析:

① 先判断条件,如果条件为TRUE,则执行条件结构体内部的内容。(www.61k.com]

② 在PL/SQL块中可以使用事务控制语句,该COMMIT同时也能把PL/SQL块外没有提

交的数据一并提交,使用时需要注意。

? IF-THEN-ELSE

语法格式:IF-THEN-ELSE

oracle教程 Oracle经典入门教程

表4 PL/SQL中条件语法

语法解析:

把ELSE与IF-THEN连在一起使用,如果IF条件不成立则执行就会执行ELSE部分的语句。

案例2:查询JAMES的工资,如果大于900元,则发奖金800元,否则发奖金400元。

代码演示:IF-THEN-ELSE应用

DECLARE

newSal emp.sal % TYPE;

BEGIN

SELECT sal INTO newSal FROM emp

WHERE ename='JAMES';

IF newSal>900 THEN

oracle教程 Oracle经典入门教程

UPDATE emp

SET comm=800

WHERE ename='JAMES';

ELSE

UPDATE emp

SET comm=400

WHERE ename='JAMES';

END IF; END;

? IF-THEN-ELSIF

语法格式:IF-THEN-ELSIF

oracle教程 Oracle经典入门教程

表5 PL/SQL中多分枝条件语法 语法解析:

PL/SQL中的再次条件判断中使用关键字ELSIF,而C#使用else if。(www.61k.com]

案例3:查询JAMES的工资,如果大于1500元,则发放奖金100元,如果工作大于900元,则发奖金800元,否则发奖金400元。

代码演示:IF-THEN-ELSIF应用

DECLARE

newSal emp.sal % TYPE;

BEGIN

SELECT sal INTO newSal FROM emp

oracle教程 Oracle经典入门教程

WHERE ename='JAMES';

IF newSal>1500 THEN

UPDATE emp

SET comm=1000

WHERE ename='JAMES';

ELSIF newSal>1500 THEN

UPDATE emp

SET comm=800

WHERE ename='JAMES';

ELSE

UPDATE emp

SET comm=400

WHERE ename='JAMES';

END IF; END;

? CASE

CASE是一种选择结构的控制语句,可以根据条件从多个执行分支中选择相应的执行动作。(www.61k.com)也可以作为表达式使用,返回一个值。类似于C#中的switch语句。语法是:

语法格式:CASE

CASE [selector]

WHEN 表达式1 THEN 语句序列1;

WHEN 表达式2 THEN 语句序列2;

WHEN 表达式3 THEN 语句序列3;

……

[ELSE 语句序列N]; END CASE;

语法解析:

如果存在选择器selector,选择器selector与WHEN后面的表达式匹配,匹配成功就执

案例4:输入一个字母A、B、C分别输出对应的级别信息。

代码演示:CASE中存在selector,不返回值 行THEN后面的语句。如果所有表达式都与selector不匹配,则执行ELSE后面的语句。

oracle教程 Oracle经典入门教程

DECLARE

v_grade CHAR(1):=UPPER('&p_grade'); ①

BEGIN

CASE v_grade ②

WHEN 'A' THEN

dbms_output.put_line('Excellent');

WHEN 'B' THEN

dbms_output.put_line('Very Good');

WHEN 'C' THEN

dbms_output.put_line('Good');

ELSE

dbms_output.put_line('No such grade');

END CASE; END;

代码解析:

① & grade表示在运行时由键盘输入字符串到grade变量中。[www.61k.com)

② v_grade分别于WHEN后面的值匹配,如果成功就执行WHEN后的程序序列。

CASE语句还可以作为表达式使用,返回一个值。

代码演示:CASE中存在selector,作为表达式使用

DECLARE

v_grade CHAR(1):=UPPER('&grade');

p_grade VARCHAR(20) ;

BEGIN

p_grade := ①

CASE v_grade

WHEN 'A' THEN

'Excellent'

WHEN 'B' THEN

'Very Good'

WHEN 'C' THEN

'Good'

ELSE

'No such grade'

END;

dbms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade);

oracle教程 Oracle经典入门教程

END;

代码解析:

① CASE语句可以返回一个结果给变量p_grade

PL/SQL还提供了搜索CASE语句。[www.61k.com]也就是说,不使用CASE中的选择器,直接在WHEN后面判断条件,第一个条件为真时,执行对应THEN后面的语句序列。

代码演示:搜索CASE

DECLARE

v_grade CHAR(1):=UPPER('&grade');

p_grade VARCHAR(20) ;

BEGIN

p_grade :=

CASE

WHEN v_grade='A' THEN

'Excellent'

WHEN v_grade='B' THEN

'Very Good'

WHEN v_grade='C' THEN

'Good'

ELSE

'No such grade'

END;

dbms_output.put_line('Grade:' ||v_grade||',the result is '||p_grade); END;

? 循环结构

PL/SQL提供了丰富的循环结构来重复执行一些列语句。Oracle提供的循环类型有:

1. 无条件循环LOOP-END LOOP语句

2. WHILE循环语句

3. FOR循环语句

在上面的三类循环中EXIT用来强制结束循环,相当于C#循环中的break。

? LOOP循环

oracle教程 Oracle经典入门教程

LOOP循环是最简单的循环,也称为无限循环,LOOP和END LOOP是关键字。(www.61k.com]

语法格式:LOOP循环

LOOP

--循环体

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

END LOOP;

语法格式:

1. 循环体在LOOP和END LOOP之间,在每个LOOP循环体中,首先执行循环体中的语

句序列,执行完后再重新开始执行。

2. 在LOOP循环中可以使用EXIT或者[EXIT WHEN 条件]的形式终止循环。否则该循环

就是死循环。

案例5:执行1+2+3+…+100的值

代码演示:LOOP循环

DECLARE

counter number(3):=0;

sumResult number:=0;

BEGIN

LOOP

counter := counter+1;

sumResult := sumResult+counter;

IF counter>=100 THEN ①

EXIT;

END IF;

-- EXIT WHEN counter>=100; ②

END LOOP;

dbms_output.put_line('result is :'||to_char(sumResult)); END;

代码解析:

① LOOP循环中可以使用IF结构嵌套EXIT关键字退出循环

② 注释行,该行可以代替①中的循环结构,WHEN后面的条件成立时跳出循环。

? WHILE循环

oracle教程 Oracle经典入门教程

与C#中的while循环很类似。(www.61k.com)先判断条件,条件成立再执行循环体。

语法格式:WHILE

oracle教程 Oracle经典入门教程

案例6:WHILE循环

代码演示:WHILE循环

DECLARE counter number(3):=0;

sumResult number:=0;

BEGIN

WHILE counter<100 LOOP

counter := counter+1;

sumResult := sumResult+counter;

END LOOP;

dbms_output.put_line('result is :'||sumResult);

END; 表5 PL/SQL中LOOP语法

? FOR循环

FOR循环需要预先确定的循环次数,可通过给循环变量指定下限和上限来确定循环运行的次数,然后循环变量在每次循环中递增(或者递减)。FOR循环的语法是:

语法格式:FOR循环

FOR 循环变量 IN [REVERSE] 循环下限..循环上限 LOOP LOOP

--循环体

END LOOP;

语法解析:

循环变量:该变量的值每次循环根据上下限的REVERSE关键字进行加1或者减1。

oracle教程 Oracle经典入门教程

REVERSE:指明循环从上限向下限依次循环。[www.61k.com)

案例7:FOR循环

代码演示:FOR循环

DECLARE

counter number(3):=0;

sumResult number:=0;

BEGIN

FOR counter IN 1..100 LOOP

sumResult := sumResult+counter;

END LOOP;

dbms_output.put_line('result is :'||sumResult); END;

? 顺序结构

在程序顺序结构中有两个特殊的语句。GOTO和NULL

? GOTO语句

GOTO语句将无条件的跳转到标签指定的语句去执行。标签是用双尖括号括起来的标示符,在PL/SQL块中必须具有唯一的名称,标签后必须紧跟可执行语句或者PL/SQL块。GOTO不能跳转到IF语句、CASE语句、LOOP语句、或者子块中。

? NULL语句

NULL语句什么都不做,只是将控制权转到下一行语句。NULL语句是可执行语句。NULL语句在IF或者其他语句语法要求至少需要一条可执行语句,但又不需要具体操作的地方。比如GOTO的目标地方不需要执行任何语句时。

案例8:GOGO 和 NULL

代码演示:GOTO和NULL DECLARE

oracle教程 Oracle经典入门教程

sumsal emp.sal%TYPE;

BEGIN

SELECT SUM(sal) INTO sumsal FROM EMP;

IF sumsal>20000 THEN

GOTO first_label; ①

ELSE

GOTO second_label; ②

END IF;

<<first_label>> ③

dbms_output.put_line('ABOVE 20000:' || sumsal);

<<second_label>> ④

NULL; END;

代码解析:

① 跳转到程序first_label位置,就是②的位置,first_label是一个标签,用两个尖括号

包含。(www.61k.com]

② 无条件跳转到sedond_label位置,就是④的位置。④处不执行任何内容,因此是一

个NULL语句。

与C#一样,在PL/SQL中,各种循环之间可以相互嵌套。

5. PL/SQL中动态执行SQL语句

在PL/SQL程序开发中,可以使用DML语句和事务控制语句,但是还有很多语句(比如DDL语句)不能直接在PL/SQL中执行。这些语句可以使用动态SQL来实现。

PL/SQL块先编译然后再执行,动态SQL语句在编译时不能确定,只有在程序执行时把SQL语句作为字符串的形式由动态SQL命令来执行。在编译阶段SQL语句作为字符串存在,程序不会对字符串中的内容进行编译,在运行阶段再对字符串中的SQL语句进行编译和执行,动态SQL的语法是:

语法格式:动态SQL

EXECUTE IMMEDIATE 动态语句字符串

[INTO 变量列表]

[USING 参数列表]

oracle教程 Oracle经典入门教程

语法解析:

代码演示:动态SQL

DECLARE

sql_stmt VARCHAR2(200); --动态SQL语句

emp_id NUMBER(4) := 7566;

salary NUMBER(7,2);

dept_id NUMBER(2) := 90;

dept_name VARCHAR2(14) := 'PERSONNEL';

location VARCHAR2(13) := 'DALLAS';

emp_rec emp%ROWTYPE;

BEGIN

--无子句的execute immediate

EXECUTE IMMEDIATE 'CREATE TABLE bonus1 (id NUMBER, amt NUMBER)'; ① ----using子句的execute immediate

sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';

EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location; ② ----into子句的execute immediate

sql_stmt := 'SELECT * FROM emp WHERE empno = :id';

EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id; ③

----returning into子句的execute immediate

sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1

RETURNING sal INTO :2';

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary; ④

EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num'

USING dept_id; ⑤ END; 如果动态语句是SELECT语句,可以把查询的结果保存到INTO后面的变量中。(www.61k.com]如果动态动态SQL中的参数格式是:[:参数名],参数在运行时需要使用USING传值。 案例9:动态SQL 语句中存在参数,USING为语句中的参数传值。

代码解析:

① 动态执行一个完整的SQL语句。

② SQL语句中存在3个参数分别标识为:[:1、:2、:3],因此需要用USING关键字对三

oracle教程 Oracle经典入门教程

个参数分别赋值。[www.61k.com)

③ 对动态查询语句可以使用INTO子句把查询的结果保存到一个变量中,要求该结果

只能是单行。

④ 在Oracle的insert,update,delete语句都可以使用RETURNING子句把操作影响的

行中的数据返回,对SQL语句中存在RETURNING子句时,在动态执行时可以使用RETURNING INTO来接收。

⑤ 动态执行参数中可以是:[:数字]也可以是[:字符串]。

6. PL/SQL的异常处理

在程序运行时出现的错误,称为异常。发生异常后,语句将停止执行,PL/SQL引擎立即将控制权转到PL/SQL块的异常处理部分。异常处理机制简化了代码中的错误检测。PL/SQL中任何异常出现时,每一个异常都对应一个异常码和异常信息。比如:

oracle教程 Oracle经典入门教程

图1 PL/SQL中的异常

? 预定义异常

为了Oracle开发和维护的方便,在Oracle异常中,为常见的异常码定义了对应的异常名称,称为预定义异常,常见的预定义异常有:

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

表6 PL/SQL中预定义异常

语法格式:异常处理

BEGIN

--可执行部分 EXCEPTION -- 异常处理开始

WHEN 异常名1 THEN --对应异常处理 --对应异常处理 PL/SQL中用EXCEPTION关键字开始异常处理。[www.61k.com)具体语法是: WHEN 异常名2 THEN …… WHEN OTHERS THEN END; --其他异常处理

语法解析:

代码演示:异常处理

SQL> DECLARE

2 newSal emp.sal % TYPE;

3 BEGIN

4 SELECT sal INTO newSal FROM emp; 5 EXCEPTION

6 WHEN TOO_MANY_ROWS THEN

7 dbms_output.put_line('返回的记录太多了'); 8 WHEN OTHERS THEN

9 dbms_output.put_line('未知异常'); 10 END;

11 /

返回的记录太多了 异常发生时,进入异常处理部分,具体的异常与若干个WHEN子句中指明的异常名匹配,匹配成功就进入对应的异常处理部分,如果对应不成功,则进入OTHERS进行处理。 案例10 :异常处理

oracle教程 Oracle经典入门教程

PL/SQL procedure successfully completed

? 自定义异常。[www.61k.com]

除了预定义异常外,用户还可以在开发中自定义异常,自定义异常可以让用户采用与

? 异常定义:在PL/SQL块的声明部分采用EXCEPTION关键字声明异常,定义方法与

定义变量相同。比如声明一个myexception异常方法是:

myexception EXCEPTION;

? 异常引发:在程序可执行区域,使用RAISE关键字进行引发。比如引发myexception

方法是:

RAISE myexception;

代码演示:自定义异常

SQL> DECLARE

2 sal emp.sal%TYPE;

3 myexp EXCEPTION; ①

4 BEGIN

5 SELECT sal INTO sal FROM emp WHERE ename='JAMES';

6 IF sal<5000 THEN

7 RAISE myexp; ②

8 END IF;

9 EXCEPTION

10 WHEN NO_DATA_FOUND THEN

11 dbms_output.put_line('NO RECORDSET FIND!');

12 WHEN MYEXP THEN ③

13 dbms_output.put_line('SAL IS TO LESS!');

14 END;

15 /

SAL IS TO LESS! PL/SQL procedure successfully completed PL/SQL引擎处理错误相同的方式进行处理,用户自定义异常的两个关键点: 案例11:自定义异常

代码解析:

① 用EXCEPTION定义一个异常变量myexp

oracle教程 Oracle经典入门教程

② 在一定条件下用RAISE引发异常myexp

③ 在异常处理部分,捕获异常,如果不处理异常,该异常就抛给程序执行者。[www.61k.com]

? 引发应用程序异常

在Oracle开发中,遇到的系统异常都有对应的异常码,在应用系统开发中,用户自定义的异常也可以指定一个异常码和异常信息,Oracle系统为用户预留了自定义异常码,其范围介于-20000到-20999之间的负整数。引发应用程序异常的语法是:

RAISE_APPLICATION_ERROR(异常码,异常信息)

案例12:引发系统异常

代码演示:引发应用系统异常

SQL> DECLARE

2 sal emp.sal%TYPE;

3 myexp EXCEPTION;

4 BEGIN

5 SELECT sal INTO sal FROM emp WHERE ename='JAMES';

6 IF sal<5000 THEN

7 RAISE myexp;

8 END IF;

9 EXCEPTION

10 WHEN NO_DATA_FOUND THEN

11 dbms_output.put_line('NO RECORDSET FIND!');

12 WHEN MYEXP THEN

13 RAISE_APPLICATION_ERROR(-20001,'SAL IS TO LESS!'); ①

14 END;

15 /

ORA-20001: SAL IS TO LESS! ②

ORA-06512: 在 line 14

代码解析:

① 引发应用系统异常,指明异常码和异常信息。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

② 在控制台上显示异常码和异常信息。

如果要处理未命名的内部异常,必须使用OTHERS异常处理器。也可以利用PRAGMA EXCEPTION_INIT把一个异常码与异常名绑定。

oracle教程 Oracle经典入门教程

PRAGMA由编译器控制,PRAGMA在编译时处理,而不是在运行时处理。(www.61k.com]EXCEPTION_INIT告诉编译器将异常名与ORACLE错误码绑定起来,这样可以通过异常名引用任意的内部异常,并且可以通过异常名为异常编写适当的异常处理器。PRAGMA EXCEPTION_INIT的语法是:

PRAGMA EXCEPTION_INIT(异常名,异常码)

这里的异常码可以是用户自定义的异常码,也可以是Oracle系统的异常码。

案例13:PRAGMA EXCEPTION_INIT异常

代码演示:PRAGMA EXCEPTION_INIT异常

<<outterseg>>

DECLARE

null_salary EXCEPTION;

PRAGMA EXCEPTION_INIT(null_salary, -20101); ①

BEGIN

<<innerStart>> ②

DECLARE

curr_comm NUMBER;

BEGIN

SELECT comm INTO curr_comm FROM emp WHERE empno = &empno;

IF curr_comm IS NULL THEN

RAISE_APPLICATION_ERROR(-20101, 'Salary is missing'); ③

ELSE

dbms_output.put_line('有津贴');

END IF;

END;

EXCEPTION

WHEN NO_DATA_FOUND THEN

dbms_output.put_line('没有发现行');

WHEN null_salary THEN

dbms_output.put_line('津贴未知'); ④

WHEN OTHERS THEN

dbms_output.put_line('未知异常'); END;

代码解析:

oracle教程 Oracle经典入门教程

① 把异常名称null_salary与异常码-20101关联,该语句由于是预编译语句,必须放在

声明部分。[www.61k.com)也就是说-20101的异常名称就是null_salary。

② 嵌套PL/SQL语句块

③ 在内部PL/SQL语句块中引发应用系统异常-20101。

④ 在外部的PL/SQL语句块中就可以用异常名null_salary进行捕获。

oracle教程 Oracle经典入门教程

7. 本章总结

? PL/SQL是一种块结构的语言,它将一组语句放在一个块中,一次性发送给服务器,

PL/SQL引擎把接收到PL/SQL语句块中的内容进行分析,把其中的过程控制语句由PL/SQL引擎自身去执行,把PL/SQL语句块中的SQL语句交给服务器的SQL语句执行器执行。[www.61k.com]

? PL/SQL的数据类型包括标量数据类型,引用数据类型和存储文本、图像、视频、

声音等非结构化得大数据类型(LOB数据类型)等。

? Oracle中存在两种属性类型:%TYPE和%ROWTYPE。

? PL/SQL程序可通过控制结构来控制命令执行的流程。PL/SQL中提供三种程序结构:

顺序结构、条件结构和循环结构。

? 在PL/SQL程序开发中,可以使用DML语句和事务控制语句,还可以动态执行SQL

语句,动态执行SQL语句的命令是:EXECUTE IMMEDIATE。

? 在程序运行时出现的错误,称为异常。发生异常后,语句将停止执行,PL/SQL引

擎立即将控制权转到PL/SQL块的异常处理部分。PL/SQL中任何异常出现时,每一个异常都对应一个异常码和异常信息。

oracle教程 Oracle经典入门教程

8. 本章练习

1. PL/SQL有哪些优点?

2. 请描述PL/SQL块的结构。[www.61k.com)

3. 请描述多分枝判断CASE的用法。

4. PL/SQL中有哪些循环控制语句?如何使用它们?

5. 如何执行动态SQL语句?

6. 如何自定义异常,如何把自定义异常与异常码绑定?

7. 编写一个程序,输入一个整数,使用循环结构将该数字左右翻转,输出翻转后的结

果。

8. 编写一个程序,在EMP表查找姓名为ALLEN员工,并获取TOO_MANY_ROWS和

NO_DATA_FOUND异常。

9. 编写一个过程为班级每位同学创建一个用户,用户名和密码都是:“班级号+学号”,

并为每位用户授权:CONNECT和RESOURCE。

oracle教程 Oracle经典入门教程

章节知识结构图

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

第6章

Oracle应用于.Net平台

主要内容 ? 回顾ADO.NET

? 使用ADO.NET连接Oracle

? 抽象工厂加入Oracle

oracle教程 Oracle经典入门教程

1. 回顾ADO.NET

ADO.NET是一组用于和数据源进行交互的面向对象类库集,它存在于.Net Framework中。[www.61k.com)通常情况下,数据源可以是各种类型的数据库,利用ADO.NET可以访问目前几乎所有的主流数据库,如Oracle、SQL Server、DB2、Access等,但数据源同样也能够是文本文件、Excel文件或者XML文件,因此,ADO.NET可以访问的数据源是很多的。

ADO.NET由两部分组成:.Net数据提供程序和数据集。

? .Net数据提供程序

ADO.NET提供了与常用的各种数据源进行交互的一些公共方法,但是对于不同的数据源由于它们各采用的协议是不一样的,所以会采用不同的类库,这些类库称为数据提供程序。主要的数据提供程序如表1所示:

oracle教程 Oracle经典入门教程

表1 主要的.NET数据提供程序

ADO.NET主要负责与数据库服务器建立连接通道,并基于此连接通道实现从数据库中检索数据,并将内存中的数据回送到数据库以提交更新或将在内存中拼写好的SQL语句提交到数据库服务器并执行以实现某种数据操作等等。

? 数据集

数据集可以被看作是一个存储在内存中的离线式的数据库,它很像我们最终存储数据的物理数据库,它将很多物理数据库的机制搬到了内存中。

ADO.NET的主要部分已经在之前的章节介绍过了,例如:利用SQL Server.NET链接SQL

oracle教程 Oracle经典入门教程

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

Server数据库。(www.61k.com)本章将主要介绍利用ADO.NET连接Oracle数据库,实现数据的存取。ADO.NET的结构如图1所示。

oracle教程 Oracle经典入门教程

图1 ADO.NET结构图

2. 使用ADO.NET连接Oracle

使用ADO.NET数据访问技术连接Oracle数据库和连接Sql Server数据库的步骤基本相同:

1. 使用Connection对象建立数据库连接。

2. 使用Command对象执行数据库操作。

3. 采用连线或者断线的方式进行数据的存取。

4. 使用Connection对象的Close方法关闭数据库连接。

连接Sql Server数据库和Oracle数据库所使用的数据提供程序是不一样的,连接Sql Server数据库使用的是SqlServer.NET,包括SqlConnection、SqlCommand等数据访问类。而连接Oracle数据库则使用的是Oracle.NET,包括OracleConnection、OracleCommand等数据访问类,包含在System.Data.OracleClient命名空间下,由于该命名空间默认并没有被添加到项目中来,所以在使用前需要如图2所示添加响应的引用才能使用。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图2 添加System.Data.OracleClient引用

案例1:在Oracle数据库中在System用户下,创建UserInfo表,并插入一定数据,使用ADO.NET数据访问技术将UserInfo表中的数据检索出来,并显示在ASP.NET页面中。(www.61k.com)UserInfo表中的数据如图3所示。

oracle教程 Oracle经典入门教程

图2 UserInfo表中数据

实现步骤:

1. 使用OracleConnection对象建立与Oracle之间的连接。

代码演示:建立连接

//连接字符串

string connectionString = "Data Source=MYORCL;User

ID=System;Password=accp;Unicode=True";

//创建Oracle连接对象 OracleConnection con = new OracleConnection(connectionString);

oracle教程 Oracle经典入门教程

//打开连接 con.Open();

2. 创建命令行对象,准备执行检索数据库操作。[www.61k.com]

代码演示:建立命令行对象

//建立Sql查询语句

string sql = "select * from userinfo";

//创建Oracle命令行对象

OracleCommand cmd = new OracleCommand(sql, con); //执行命令行对象

OracleDataReader odr =

cmd.ExecuteReader(CommandBehavior.CloseConnection);

3. 创建实体类,并遍历结果集,将数据存放到集合中存储。

代码演示:创建实体类

//实体类

public class UserInfo

{

int userID;

public int UserID

{

get { return userID; }

set { userID = value; }

}

string userName;

public string UserName

{

get { return userName; }

set { userName = value; }

}

string userAge;

public string UserAge

oracle教程 Oracle经典入门教程

{

get { return userAge; }

set { userAge = value; }

} }

代码演示:遍历结果集

//遍历结果集

IList<UserInfo> users = new List<UserInfo>();

while (odr.Read())

{

UserInfo user = new UserInfo();

user.UserID = Convert.ToInt32(odr["UserID"]);

user.UserName = Convert.ToString(odr["UserName"]);

user.UserAge = Convert.ToString(odr["UserAge"]);

users.Add(user); }

4. 将集合中的数据绑定到GridView控件上显示出来。(www.61k.com]

代码演示:绑定数据

//绑定DataGridView控件

this.GridView1.DataSource = users; this.GridView1.DataBind();

根据上面的操作,不难看出连接Oracle数据库与连接SqlServer数据库除了数据提供程序方面有所区别之外,从操作步骤和实现原理等方面看区别不大。按照上面步骤操作,在页面中运行的效果如图3所示。增删改操作和检索操作基本相似,在这里就不再叙述了。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图3 案例效果

3. 抽象工厂中加入Oracle

在设计模式中介绍过抽象工厂设计模式(Abstract Factory),抽象工厂有四种关键角色:抽象工厂、实体工厂、抽象产品、实体产品。[www.61k.com]抽象工厂模式实现原理强调的是对象组合机制,由在“父工厂”内定义不同的“子工厂”对象来负责不同的目标对象的创建,也就是说利用实体产品由抽象产品来约束,而由实体工厂来创建,实体工厂则由抽象工厂约束,可以有效的发挥工厂模式管理清晰的优点。

案例2:采用抽象工厂模式实现在学员信息管理系统中支持Access、SQLServer以及Oracle三套数据库的切换(以学员基本信息模块为例),以学员基本信息模块为例给出概要的实现,并实现展示所有学生信息功能。

案例分析:本例是抽象工厂课堂案例的延续,需要在项目中多添加一个Oracle数据库,实体产品是数据访问对象,三套数据库相当于有三套数据库访问对象,通过三个实体工厂管理三套数据库访问对象,最后使用抽象工厂管理三个实体工厂。

实现步骤:

1. 在Oracle数据库中使用Sql语句新建Infos表,并添加约束和表数据,如图3所示:

oracle教程 Oracle经典入门教程

图3 Student表数据

oracle教程 Oracle经典入门教程

2. 在VS2008中创建空白解决方案,命名为Test.sln。(www.61k.com)

3. 在解决方案中添加表示层,并添加StudentList.aspx页面。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

4. 在解决方案中添加模型层,根据上面的表结构新建Student.cs实体类。

代码演示:Student类

public class Student

{

string stuID;

public string StuID

{

get { return stuID; }

set { stuID = value; }

}

/**

* 其他成员… …

*/ }

5. 在解决方案中添加数据访问层IDAL(抽象产品)。

代码演示:抽象产品

public interface IStudentService

{

//获取所有学生信息

IList<Student> GetAllStudents(); }

6. 在解决方案中添加数据访问层DAL(实体产品),并利用文件夹将不同的实体产品

分类,如图4所示。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图4 实体产品

代码演示:实体产品

/// <summary>

/// 获得所有学生信息

/// </summary>

/// <returns>所有学生信息集合</returns>

public IList<Student> GetAllStudents()

{

//创建SQL语句

string sql = "select * from sys.infos";

//创建泛型集合

IList<Student> students = new List<Student>();

//执行SQL语句得到结果集

OracleDataReader odr = dbh.ExecuteReader(sql);

//遍历结果集

while(odr.Read())

{

Student student = new Student();

student.StuID = Convert.ToString(odr["StuID"]);

student.StuName = Convert.ToString(odr["StuName"]);

student.StuAddress = Convert.ToString(odr["StuAddress"]); student.Seat = Convert.ToInt32(odr["Seat"]);

student.Gender = Convert.ToString(odr["Gender"]);

oracle教程 Oracle经典入门教程

student.EnRollDate = Convert.ToDateTime(odr["EnRollDate"]); student.ClassNo = Convert. ToString (odr["ClassNo"]); //添加到泛型集合

students.Add(student);

}

//返回

return students; }

7. 在解决方案中添加业务逻辑层,命名为StudentManager.cs。[www.61k.com]

代码演示:BLL层

/// <summary>

/// 获取所有学生信息

/// </summary>

/// <returns>所有学生信息集合</returns>

public IList<Student> GetAllStudents()

{

//利用抽象工厂创建实体工厂

Factory factory = Factory.CreateFactory();

//利用工厂创建产品

IStudentService iss = factory.GetStudentService();

return iss.GetAllStudents(); }

8. 在解决方案中添加抽象工厂,并添加相应实体工厂,如图5所示。

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

图5 抽象工厂

代码演示:抽象工厂

//抽象工厂

public abstract class Factory

{

public static Factory CreateFactory()

{

//采用反射技术得到配置文件中的配置信息

string factoryType = Config.FactoryType;

Factory factory =

(Factory)System.Reflection.Assembly.Load("DBFactory").CreateInstance(factoryType);

return factory;

}

//定义子类(实体工厂)的操作规则

public abstract IStudentService GetStudentService(); }

9. 在表示层添加数据展示控件,通过设定属性绑定数据提取方法,实现案例目标。(www.61k.com]

oracle教程 Oracle经典入门教程

4. 本章总结

? ADO.NET是一组用于和数据源进行交互的面向对象类库集,它存在于.Net Framework中。[www.61k.com]

通常情况下,数据源可以是各种类型的数据库,利用ADO.NET可以访问目前几乎所有的主流数据库,如Oracle、SQL Server、DB2、Access等。

? 使用ADO.NET技术访问数据库的大致步骤如下:

1. 使用Connection对象建立数据库连接。

2. 使用Command对象执行数据库操作。

3. 采用连线或者断线的方式进行数据的存取。

4. 使用Connection对象的Close方法关闭数据库连接。

? 抽象工厂有四种关键角色:抽象工厂、实体工厂、抽象产品、实体产品。

oracle教程 Oracle经典入门教程

5. 本章练习

1. 利用本章所学知识,完成如下功能:

1) 在本章完成项目基础上,继续实现对Oracle数据库的增删改操作。[www.61k.com]

2) 在StudentList.aspx页面添加查看详细链接,编写GetStudentById等方法。

3) 在StudentList.aspx页面中添加删除链接,编写DeleteStudent等方法。

4) 在StudentList.aspx页面中添加修改链接,编写UpdateStudent等方法。

oracle教程 Oracle经典入门教程

章节知识结构图

oracle教程 Oracle经典入门教程

oracle教程 Oracle经典入门教程

附录

数据库导入导出

主要内容 ? 导出

? 导入

oracle教程 Oracle经典入门教程

1. Oracle导入导出

Oracle的备份是Oracle操作中常见的工作,常见的备份方案有:逻辑备份(IMP&EXP命令进行备份)、物理文件备份(脱机及联机备份)、利用RMAN(Recovery Manager)的增量物理文件系统备份。(www.61k.com)ORACLE数据库的逻辑备份分为四种模式:表空间备份(tablespace)、表备份(table)、用户备份(user)和完全备份(full)。Oracle的逻辑备份是使用IMP&EXP命令进行数据导入导出的操作。使用EXP命令导出或者使用IMP命令导入时,需要Create Session系统权限,但是如果要导出其他的表,必须拥有权限:EXP_FULL_DATABASE。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

调用导入导出命令时,首先要估计所需的空间。EXP命令导出的文件是二进制文件(*.dmp)只能由对应的IMP命令进行读取恢复。导入导出的用途是:

? 备份与恢复

? Oracle平台更换:可以在相同版本之间进行备份与恢复,Oracle较低版本的export

数据文件可以import到高版本的Oracle数据库中,但是Oracle的版本只能是相邻的,不能垮版本。

2. EXP导出数据

EXP命令可以在交互环境下导出数据库中的数据,也可以在非交互环境下执行命令。交互环境下的命令执行,是一步一步执行的过程。

代码演示:exp的交互环境

D:\>exp scott/tiger@my_orcl ①

Export: Release 10.2.0.3.0 - Production on 星期一 10月 19 17:04:14 2009

Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options

输入数组提取缓冲区大小: 4096 > ②

导出文件: EXPDAT.DMP > scott.dmp ③

(2)U(用户), 或 (3)T(表): (2)U > 2 ④

导出权限 (yes/no): yes > yes ⑤

导出表数据 (yes/no): yes > yes ⑥

压缩区 (yes/no): yes > no ⑦

已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

. 正在导出 pre-schema 过程对象和操作

oracle教程 Oracle经典入门教程

. 正在导出用户 SCOTT 的外部函数库名

. 导出 PUBLIC 类型同义词

. 正在导出专用类型同义词

. 正在导出用户 SCOTT 的对象类型定义

即将导出 SCOTT 的对象...

. 正在导出数据库链接

. 正在导出序号

. 正在导出簇定义

. 即将导出 SCOTT 的表通过常规路径...

. . 正在导出表 BONUS导出了 0 行

. . 正在导出表 DEPT导出了 10 行

. . 正在导出表 EMP导出了 14 行

. . 正在导出表 SALGRADE导出了 5 行

. . 正在导出表 TBLSTUDENT导出了 3 行

. 正在导出同义词

. 正在导出视图

. 正在导出存储过程

. 正在导出运算符

. 正在导出引用完整性约束条件

. 正在导出触发器

. 正在导出索引类型

. 正在导出位图, 功能性索引和可扩展索引

. 正在导出后期表活动

. 正在导出实体化视图

. 正在导出快照日志

. 正在导出作业队列

. 正在导出刷新组和子组

. 正在导出维

. 正在导出 post-schema 过程对象和操作

. 正在导出统计信息

成功终止导出, 没有出现警告。(www.61k.com] D:\>

代码解析:

① Exp是导出命令,该命令后面紧跟“用户名/密码@服务器网络连接”。

② Exp程序导出时使用的缓冲区大小,缓冲区越大,导出速度越快。直接回车代表使

用默认值4096B。

③ Exp命令会把所有要到处的数据导出到一个Dmp文件中,该步骤是Exp询问导出的

数据文件名称。

④ Exp程序询问导出整个用户还是导出某个表。默认导出整个用户。

⑤ Exp程序询问是否导出每张表的访问权限。默认导出访问权限。

⑥ Exp程序询问是否导出表中的数据。默认导出数据库表中的数据。

oracle教程 Oracle经典入门教程

⑦ Oracle表中的数据可能来自不同的分区中的数据块,默认导出时会把所有的数据压

缩在一个数据块上,IMP导入时,如果不存在连续一个大数据块,则会导入失败。[www.61k.com)

也可以使用Exp命令时,设置各种参数,使准备就绪的Exp命令不需要与用户交互,按照参数的要求,Exp命令会一次性执行导出工作。要指定参数,您可以使用关键字:

EXP KEYWORD=value 或 KEYWORD=(value1,value2,...,valueN)

例如: EXP SCOTT/TIGER GRANTS=Y TABLES=(EMP,DEPT,MGR)

oracle教程 Oracle经典入门教程

表1 EXP参数说明

代码演示:exp的非交互环境

D:\>exp scott/tiger file=employee.dmp tables=(emp,dept)

Export: Release 10.2.0.3.0 - Production on 星期一 10月 19 17:38:25 2009

Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production

oracle教程 Oracle经典入门教程

With the Partitioning, OLAP and Data Mining options

已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

即将导出指定的表通过常规路径...

. . 正在导出表 EMP导出了 14 行

. . 正在导出表 DEPT导出了 10 行

成功终止导出, 没有出现警告。[www.61k.com) D:\>

3. IMP导入

IMP程序导入就是把Exp导出的文件重新导入到数据库的过程。导入时也有一些重要的参数:

? Fromuser:指出导出时dmp文件中记载的用户信息。

? Touser:dmp文件要导入到什么目标用户中。

? Commit:默认是N,在缓冲区满时是否需要commit,如果设为N,需要较大的回滚段。 ? Igore: Oracle在恢复数据的过程中,当恢复某个表时,该表已经存在,就要根据ignore

参数的设置来决定如何操作。若ignore=y,Oracle不执行CREATE TABLE语句,直接将数据插入到表中,如果插入的记录违背了约束条件,比如主键约束,则出错的记录不会插入,但合法的记录会添加到表中。若ignore=n,Oracle不执行CREATE TABLE语句,同时也不会将数据插入到表中,而是忽略该表的错误,继续恢复下一个表。

代码演示:Imp导入

D:\>imp system/manager file=employee.dmp fromuser=scott touser=employee commit=y

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

Import: Release 10.2.0.3.0 - Production on 星期一 10月 19 17:54:51 2009

Copyright (c) 1982, 2005, Oracle. All rights reserved.

连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production With the Partitioning, OLAP and Data Mining options

经由常规路径由 EXPORT:V10.02.01 创建的导出文件

警告: 这些对象由 SCOTT 导出, 而不是当前用户

已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入

. 正在将 SCOTT 的对象导入到 EMPLOYEE

. . 正在导入表 "EMP"导入了 14 行

. . 正在导入表 "DEPT"导入了 10 行

即将启用约束条件...

成功终止导入, 没有出现警告。 D:\>

oracle教程 Oracle经典入门教程

4. 常见问题

? 数据库对象已经存在

一般情况, 导入数据前应该彻底删除目标数据下的表,序列,函数/过程,触发器等。[www.61k.com) 数据库对象已经存在, 按缺省的imp参数,则会导入失败。

如果用了参数ignore=y,会把exp文件内的数据内容导入。

如果表有唯一关键字的约束条件,不合条件将不被导入。

如果表没有唯一关键字的约束条件,将引起记录重复。

? 数据库对象有主外键约束

不符合主外键约束时,数据会导入失败。

解决办法: 先导入主表,再导入依存表。

disable目标导入对象的主外键约束,导入数据后,再enable它们。

? 权限不够

如果要把A用户的数据导入B用户下, A用户需要有imp_full_database权限。

? 导入大表( 大于80M ) 时,存储分配失败

默认的EXP时,compress = Y,也就是把所有的数据压缩在一个数据块上。 导入时,如果不存在连续一个大数据块,则会导入失败。

导出80M以上的大表时,记得compress= N,则不会引起这种错误。

? Imp和Exp使用的字符集不同

如果字符集不同,导入会失败,可以改变unix环境变量或者NT注册表里NLS_LANG相关信息。

? Imp和Exp版本不能往上兼容

Imp可以成功导入低版本Exp生成的文件, 不能导入高版本Exp生成的文件根据情况我们可以用。

扩展:oracle经典入门 / oracle从入门到精通 / oracle教程

三 : Smarty模板学习入门教程

smarty模版是比较大众化的一个模版,在php开发过程当中被很多开发者视为最友好的模版之一,学习smarty课程对于很多培训机构来说也是列入了培训课程之一,那么很多方面就需要我们学习了
一. 安装
首先打开网页http://sm www.61k.com .php,下载最新版本的Smarty。(www.61k.com]解压下载的文件(目录结构还蛮复杂的)。例如:
(1) 我在根目录下建立了新的目录learn/,再在learn/里建立一个文件夹smarty/。将刚才解压缩出来的目录的libs/拷贝到smarty/里, 再在smarty/里新建templates目录,templates里新建cache/,templates/,templates_c/, config/,
(2) 新建一个模板文件:index.tpl,将此文件放在learn/smarty/templates/templates目录下,代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN"" www.61k.com .dtd">
<html>
<head>
<metahttp-equiv="Content-Type" c>
<title>Smarty</title>
</head>
<body>
{$hello}
</body>
</html>
新建index.php,将此文件放在learn/下:
<?php
//引用类文件
require 'smarty/libs/Smarty.class.php';
$smarty = new Smarty;
//设置各个目录的路径,这里是安装的重点
$smarty->template_dir ="smarty/templates/templates";
$smarty->compile_dir ="smarty/templates/templates_c";
$smarty->config_dir = "smarty/templates/config";
$smarty->cache_dir ="smarty/templates/cache";
//smarty模板有高速缓存的功能,如果这里是true的话即打开caching,但是会造成网页不立即更新的问题,当然也可以通过其他的办法解决
$smarty->caching = false;
$hello = "Hello World!";
//赋值
$smarty->assign("hello",$hello);
//引用模板文件
$smarty->display('index.tpl');
?>
(3) 执行index.php就能看到Hello World!了。
二. 赋值
在模板文件中需要替换的值用大括号{}括起来,值的前面还要加$号。例如{$hello}。这里可以是数组,比如{$hello.item1},{$hello.item2}…
而PHP源文件中只需要一个简单的函数assign(var , value)。
简单的例子:
*.tpl:
Hello,{$exp.name}!Good {$exp.time}
*.php:
$hello[name]= “Mr. Green”;
$hello[time]=”morning”;
$smarty->assign(“exp”,$hello);
output:
Hello, www.61k.com !Good morning
三. 引用
网站中的网页一般header和footer是可以共用的,所以只要在每个tpl中引用它们就可以了。
示例:*.tpl:
{include file="header.tpl"}
{* body of template goes here *}
{include file="footer.tpl"}
四. 判断
模板文件中可以使用if else等判断语句,即可以将一些逻辑程序放在模板里。"eq","ne", "neq", "gt", "lt","lte", "le", "gte" "ge","is even", "is odd", "is not even", "is notodd", "not", "mod", "div by", "evenby", "odd by","==","!=",">","<","<=",">="这些是if中可以用到的比较。看看就能知道什么意思吧。
示例:
{if $name eq"Fred"}
WelcomeSir.
{elseif $name eq"Wilma"}
WelcomeMa'am.
{else}
Welcome,whatever you are.
{/if}
五. 循环
在Smarty里使用循环遍历数组的方法是section,如何赋值遍历都是在模板中解决,php源文件中只要一个assign就能解决问题。
示例:
{* this examplewill print out all the values of the $custid array *}
{secti loop=$custid}
id: {$custid[customer]}<br>
{/section}
OUTPUT:
id: 1000<br>
id: 1001<br>
id: 1002<br>
六. 常见问题
Smarty将所有大括号{}里的东西都视为自己的逻辑程序,于是我们在网页中想插入javascrīpt函数就需要literal的帮忙了,literal的功能就是忽略大括号{}。
示例:
{literal}
<scrīptlanguage=javascrīpt>
function isblank(field) {
if (field.value == '')
{ return false; }
else
{
document.loginform.submit();
return true;
}
}
</scrīpt>
{/literal}

原文链接 www.61k.com .php/archives/183.html

四 : Lua简易入门教程

环境:lua for windows (lfW)
主页:http://luaforwindows.luaforge.net/
https://code.google.com/p/luaforwindows/

lua for windows其实是一整套Lua的开发环境,它包括:
Lua Interpreter(Lua解释器)
Lua Reference Manual(Lua参考手册) 
Quick Lua Tour (Lua快速入门)
Examples (Lua范例)
Libraries with documentation (一些Lua库和文档)
SciTE (一个很棒的多用途编辑器,已经对Lua做了特殊设置)

Lua脚本语法说明(修订) 
Lua脚本语法说明(增加lua5.1部份特性)
Lua 的语法比较简单,学习起来也比较省力,但功能却并不弱。(www.61k.com)
所以,我只简单的归纳一下Lua的一些语法规则,使用起来方便好查就可以了。估计看完了,就懂得怎么写Lua程序了。
在Lua中,一切都是变量,除了关键字。
I.  首先是注释
写一个程序,总是少不了注释的。
在Lua中,你可以使用单行注释和多行注释。
单行注释中,连续两个减号"--"表示注释的开始,一直延续到行末为止。相当于C++语言中的"//"。
多行注释中,由"--[["表示注释开始,并且一直延续到"]]"为止。这种注释相当于C语言中的"/*...*/"。在注释当中,"[["和"]]"是可以嵌套的(在lua5.1中,中括号中间是可以加若干个"="号的,如 [==[ ... ]==]),见下面的字符串表示说明。

II.  Lua编程
经典的"Hello world"的程序总是被用来开始介绍一种语言。在Lua中,写一个这样的程序很简单:
print("Hello world")
在Lua中,语句之间可以用分号";"隔开,也可以用空白隔开。一般来说,如果多个语句写在同一行的话,建议总是用分号隔开。
Lua 有好几种程序控制语句,如:
控制语句      格式      示例
If      if 条件 then ... elseif 条件 then ... else ... end      if 1+1=2 then print("true")
elseif 1+2~=3 then print("true")
else print("false") end

While      while 条件 do ... end      while 1+1~=2 do print("true") end

Repeat      repeat ... until 条件      repeat print("Hello") until 1+1~=2

For      for 变量=初值, 终点值, 步进 do ... end      for i = 1, 10, 2 do print(i) end

For      for 变量1, 变量2, ... 变量n in 表或枚举函数 do ... end      for a,b in mylist do print(a, b) end


注意一下,for的循环变量总是只作用于for的局部变量;当省略步进值时,for循环会使用1作为步进值。
使用break可以用来中止一个循环。
相对C语言来说,Lua有几个地方是明显不同的,所以面要特别注意一下:

.语句块
语句块在C中是用"{"和"}"括起来的,在Lua中,它是用do 和 end 括起来的。比如:
do print("Hello") end
可以在 函数 中和 语句块 中定局部变量。

.赋值语句
赋值语句在Lua被强化了。它可以同时给多个变量赋值。
例如:
a,b,c,d=1,2,3,4
甚至是:
a,b=b,a  -- 多么方便的交换变量功能啊。
在默认情况下,变量总是认为是全局的。假如需要定义局部变量,则在第一次赋值的时候,需要用local说明。比如:
local a,b,c = 1,2,3  -- a,b,c都是局部变量

.数值运算
和C语言一样,支持 +, -, *, /。但Lua还多了一个"^"。这表示指数乘方运算。比如2^3 结果为8, 2^4结果为16。
连接两个字符串,可以用".."运处符。如:
"This a " .. "string." -- 等于 "this a string"

.比较运算
比较符号      <      >      <=      >=      ==      ~=
含义      小于      大于      小于或等于      大于或等于      相等      不相等

所有这些操作符总是返回true或false。
对于Table,Function和Userdata类型的数据,只有 == 和 ~=可以用。相等表示两个变量引用的是同一个数据。比如:
a={1,2}
b=a
print(a==b, a~=b)  --输出 true, false
a={1,2}
b={1,2}
print(a==b, a~=b)  --输出 false, true
.逻辑运算
and, or, not
其中,and 和 or 与C语言区别特别大。
在这里,请先记住,在Lua中,只有false和nil才计算为false,其它任何数据都计算为true,0也是true!
and 和 or的运算结果不是true和false,而是和它的两个操作数相关。
a and b:如果a为false,则返回a;否则返回b
a or b:如果 a 为true,则返回a;否则返回b

举几个例子:
print(4 and 5) --输出 5
print(nil and 13) --输出 nil
print(false and 13) --输出 false
print(4 or 5) --输出 4
print(false or 5) --输出 5


在Lua中这是很有用的特性,也是比较令人混洧的特性。
我们可以模拟C语言中的语句:x = a? b : c,在Lua中,可以写成:x = a and b or c。

扩展:lua教程 / lua / norm


最有用的语句是: x = x or v,它相当于:if not x then x = v end 。

.运算符优先级,从低到高顺序如下:
    or
    and
    <    >    <=  >=  ~=  ==
    .. (字符串连接)
    +    -
    *    /    %
    not  #(lua5.1 取长度运算)    - (一元运算)
    ^
和C语言一样,括号可以改变优先级。

III.  关键字
关键字是不能做为变量的。Lua的关键字不多,就以下几个:
    
and      break      do      else      elseif      
end      false      for      function      if      
in      local      nil      not      or      
repeat      return      then      true      until      while

IV.  变量类型
怎么确定一个变量是什么类型的呢?大家可以用type()函数来检查。Lua支持的类型有以下几种:
Nil      空值,所有没有使用过的变量,都是nil。nil既是值,又是类型。
Boolean      布尔值,只有两个有效值:true和false
Number      数值,在Lua里,数值相当于C语言的double
String      字符串,如果你愿意的话,字符串是可以包含"\0"字符的(这和C语言总是以"\0"结尾是不一样的)
Table      关系表类型,这个类型功能比较强大,请参考后面的内容。
Function      函数类型,不要怀疑,函数也是一种类型,也就是说,所有的函数,它本身就是一个变量。
Userdata      嗯,这个类型专门用来和Lua的宿主打交道的。宿主通常是用C和C++来编写的,在这种情况下,Userdata可以是宿主的任意数据类型,常用的有Struct和指针。
Thread      线程类型,在Lua中没有真正的线程。Lua中可以将一个函数分成几部份运行。如果感兴趣的话,可以去看看Lua的文档。
现在回过头来看看,倒觉得不是线程类型。反而象是用来做遍历的,象是Iterator函数。
如:
function range(n)
  local i = 0
  while(i < n) do 
  coroutine.yield( i )
  i = i + 1
  end
end
可惜的是要继续运行,需要coroutine.resume函数,有点鸡肋。请指教。

V.  变量的定义
所有的语言,都要用到变量。在Lua中,不管在什么地方使用变量,都不需要声明,并且所有的这些变量总是全局变量,除非我们在前面加上"local"。这一点要特别注意,因为我们可能想在函数里使用局部变量,却忘了用local来说明。
至于变量名字,它是大小写相关的。也就是说,A和a是两个不同的变量。
定义一个变量的方法就是赋值。"="操作就是用来赋值的
我们一起来定义几种常用类型的变量吧。
A.  Nil
正如前面所说的,没有使用过的变量的值,都是Nil。有时候我们也需要将一个变量清除,这时候,我们可以直接给变量赋以nil值。如:
var1=nil  -- 请注意 nil 一定要小写

B.  Boolean
布尔值通常是用在进行条件判断的时候。布尔值有两种:true 和 false。在Lua中,只有false和nil才被计算为false,而所有任何其它类型的值,都是true。比如0,空串等等,都是true。不要被 C语言的习惯所误导,0在Lua中的的确确是true。你也可以直接给一个变量赋以Boolean类型的值,如:
theBoolean = true

C.  Number
在Lua中,是没有整数类型的,也不需要。一般情况下,只要数值不是很大(比如不超过100,000,000,000,000),是不会产生舍入误差的。在WindowsXP能跑的当今主流PC上,实数的运算并不比整数慢。
实数的表示方法,同C语言类似,如:
4 0.4 4.57e-3 0.3e12 5e+20

D.  String
字符串,总是一种非常常用的高级类型。在Lua中,我们可以非常方便的定义很长很长的字符串。
字符串在Lua中有几种方法来表示,最通用的方法,是用双引号或单引号来括起一个字符串的,如:
"That's go!"

'Hello world!'

和C语言相同的,它支持一些转义字符,列表如下:
\a  bell
\b  back space
\f  form feed
\n  newline
\r  carriage return
\t  horizontal tab
\v  vertical tab
\\  backslash

扩展:lua教程 / lua / norm


\"  double quote
\"  single quote
\[  left square bracket
\]  right square bracket

由于这种字符串只能写在一行中,因此,不可避免的要用到转义字符。加入了转义字符的串,看起来实在是不敢恭维,比如:
"one line\nnext line\n\"in quotes\", "in quotes""
一大堆的"\"符号让人看起来很倒胃口。如果你与我有同感,那么,我们在Lua中,可以用另一种表示方法:用"[["和"]]"将多行的字符串括起来。(lua5.1: 中括号中间可以加入若干个"="号,如 [==[ ... ]==],详见下面示例)
示例:下面的语句所表示的是完全相同的字符串:
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]

值得注意的是,在这种字符串中,如果含有单独使用的"[["或"]]"就仍然得用"\["或"\]"来避免歧义。当然,这种情况是极少会发生的。

E.  Table
关系表类型,这是一个很强大的类型。我们可以把这个类型看 作是一个数组。只是C语言的数组,只能用正整数来作索引;在Lua中,你可以用任意类型来作数组的索引,除了nil。同样,在C语言中,数组的内容只允许 一种类型;在Lua中,你也可以用任意类型的值来作数组的内容,除了nil。
Table的定义很简单,它的主要特征是用"{"和"}"来括起一系列数据元素的。比如:
T1 = {}  -- 定义一个空表
T1[1]=10  -- 然后我们就可以象C语言一样来使用它了。 

T1["John"]={Age=27, Gender="Male"}
这一句相当于:
T1["John"]={}  -- 必须先定义成一个表,还记得未定义的变量是nil类型吗
T1["John"]["Age"]=27
T1["John"]["Gender"]="Male"
当表的索引是字符串的时候,我们可以简写成:
T1.John={}
T1.John.Age=27
T1.John.Gender="Male"

T1.John{Age=27, Gender="Male"}
这是一个很强的特性。

在定义表的时候,我们可以把所有的数据内容一起写在"{"和"}"之间,这样子是非常方便,而且很好看。比如,前面的T1的定义,我们可以这么写:
T1=
{
10,  -- 相当于 [1] = 10
[100] = 40,
John=  -- 如果你原意,你还可以写成:["John"] =
{
Age=27,  -- 如果你原意,你还可以写成:["Age"] =27
Gender=Male  -- 如果你原意,你还可以写成:["Gender"] =Male
},
20  -- 相当于 [2] = 20
}


看起来很漂亮,不是吗?我们在写的时候,需要注意三点:
第一,所有元素之间,总是用逗号","隔开;
第二,所有索引值都需要用"["和"]"括起来;如果是字符串,还可以去掉引号和中括号;
第三,如果不写索引,则索引就会被认为是数字,并按顺序自动从1往后编;

表类型的构造是如此的方便,以致于常常被人用来代替配置文件。是的,不用怀疑,它比ini文件要漂亮,并且强大的多。

F.  Function
函数,在Lua中,函数的定义也很简单。典型的定义如下:
function add(a,b)  -- add 是函数名字,a和b是参数名字
return a+b  -- return 用来返回函数的运行结果
end 

请注意,return语言一定要写在end之前。假如我们非要在中间放上一句return,那么就应该要写成:do return end。
还记得前面说过,函数也是变量类型吗?上面的函数定义,其实相当于:
add = function (a,b) return a+b end
当重新给add赋值时,它就不再表示这个函数了。我们甚至可以赋给add任意数据,包括nil (这样,赋值为nil,将会把该变量清除)。Function是不是很象C语言的函数指针呢?

和C语言一样,Lua的函数可以接受可变参数个数,它同样是用"..."来定义的,比如:
function sum (a,b, )
如果想取得...所代表的参数,可以在函数中访问arg局部变量(表类型)得到 (lua5.1: 取消arg,并直接用"..."来代表可变参数了,本质还是arg)。
如 sum(1,2,3,4)
则,在函数中,a = 1, b = 2, arg = {3, 4}  (lua5.1:  a = 1, b = 2, ... = {3, 4})
更可贵的是,它可以同时返回多个结果,比如:
function s()
return 1,2,3,4
end
a,b,c,d = s()  -- 此时,a = 1, b = 2, c = 3, d = 4 

前面说过,表类型可以拥有任意类型的值,包括函数!因此,有一个很强大的特性是,拥有函数的表,哦,我想更恰当的应该说是对象吧。Lua可以使用面向对象编程了。不信?举例如下:
t =
{
Age = 27
add = function(self, n) self.Age = self.Age+n end
}
print(t.Age)  -- 27
t.add(t, 10)
print(t.Age)  -- 37

不过,t.add(t,10) 这一句实在是有点土对吧?没关系,在Lua中,我们可以简写成:
t:add(10)  -- 相当于 t.add(t,10)

G.  Userdata 和 Thread
这两个类型的话题,超出了本文的内容,就不打算细说了。

VI.语法

A.闭包
示例一

function newCounter()  local i = 0  return function() -- anonymous function  i = i + 1  return i  end end  c1 = newCounter() print(c1()) --> 1 print(c1()) --> 2

示例二:

function myPower(x)  return function(y) return y^x end end  power2 = myPower(2) power3 = myPower(3)  print(power2(4)) --4的2次方 print(power3(5)) --5的3次方

B.载入

我们可以直接使用require(“model_name”)来载入别的lua文件,文件的后缀是.lua。载入的时候就直接执行那个文件了。比如:

扩展:lua教程 / lua / norm


我们有一个hello.lua的文件:

print("Hello, World!")

如果我们:require(“hello”),那么就直接输出Hello, World!了。
注意:
1)require函数,载入同样的lua文件时,只有第一次的时候会去执行,后面的相同的都不执行了。
2)如果你要让每一次文件都会执行的话,你可以使用dofile(“hello”)函数
3)如果你要玩载入后不执行,等你需要的时候执行时,你可以使用 loadfile()函数,如下所示:

local hello = loadfile("hello") ... ... ... ... hello()

loadfile(“hello”)后,文件并不执行,我们把文件赋给一个变量hello,当hello()时,才真的执行。(我们多希望JavaScript也有这样的功能
当然,更为标准的玩法如下所示。
假设我们有一个文件叫mymod.lua,内容如下:
文件名:mymod.lua

local HaosModel = {}  local function getname()  return "Hao Chen" end  function HaosModel.Greeting()  print("Hello, My name is "..getname()) end  return HaosModel

于是我们可以这样使用:

local hao_model = require("mymod") hao_model.Greeting()

其实,require干的事就如下:(所以你知道为什么我们的模块文件要写成那样了)

local hao_model = (function ()  --mymod.lua文件的内容-- end)()

VI.  结束语
就这么结束了吗?当然不是,接下来,我们需要用Lua解释器,来帮助理解和实践了。相信这样会更快的对Lua上手了。
就象C语言一样,Lua提供了相当多的标准函数来增强语言的功能。使用这些标准函数,可以很方便的操作各种数据类型,并处理输入输出。有关这方面的信息,我们可以参考《Programming in Lua 》一书,也可以在网络上直接观看电子版,网址为:

备注:本文的部份内容摘、译自lua随机文档。
相关链接:
1. Lua 官方网站: http://www.lua.org 
2. Lua Wiki网站,你可以在这里找到很多相关的资料,如文档、教程、扩展,以及C/C++的包装等: http://lua-users.org/wiki/

扩展:lua教程 / lua / norm

五 : 易经学习教程(二)

《易经入门学习教程》第01章伏羲八卦

(作者:劝学网小雅)

一、宇宙的产生

宇宙是时间和空间内所包含的一切,四方上下谓之宇,古往今来谓之宙。现代物理学认为大约200亿年前,宇宙是由一质点爆炸开始逐步形成,而且还在继续膨胀。早在2500年之前,老子在《道德经》一书中,对宇宙的产生和发展就有了非常完美的描述,他说宇宙经过了“道生一、一生二、二生三,三生万物,万物负阴而抱阳,冲气以为和。”这样一个创世说,其后的庄子在详细描述“道”这个本源时补充道,“道”的大小是“至大无外,至小无内”。

中国更有一有关宇宙创生的古老传说,阴阳二气未分之时,宇宙螟涬鸿蒙,未有成形,天地日月未具,状如鸡子,混沌玄黄,盘古之神乃天地之精髓,游乎混沌之中。忽一声巨响盘古九变,开天辟地,阳清之气上升成天,化为日月星辰;阴浊之气下沉为地,化为三山五岳。天地交感,云行雨施,万物始成。

古代的传说不同于现今的网络小说,网络小说纯粹是信口开河,实乃无聊之极。古之神话大多由贤人所作,为了让没有文化的人们明白圣贤道理,形象地赋予“神”的名字,以及“神”的一些功能特点,让人们很容易记忆掌握并传播。上面道家对创世的科学定义以及神州传说,后人又结合了易经的理论,形成太极阴阳学说,这一学说很好地解释了宇宙产生的原因及过程。

周易的系辞中说:“有太极,是生两仪, 两仪生四象, 四象生八卦,八卦定吉凶,吉凶生大业。”易经认为,盘古开天地之前,也就是宇宙大爆炸之前,宇宙就是一太极(即物理学中所说“质点”),这个太极之内包含阴阳二气,阴阳二气交融在一起,相对地来说比较安静稳定的状态,这时称之为太极状态,简称太极。当内部的阴阳二气发生交融变化时,我们称之为两仪状态,简称两仪。

当阴阳两仪继续交融变化就形成了四象,所谓四象即:少阳、太阳、少阴、太阴。这可以用凌晨、中午、黄昏、夜晚来比喻。凌晨时阴阳二气大致相当,上为阳下为阴,说明天上太阳的热量尚未完全到达地面,当到了中午时分阳气最盛,所以为太阳,随后阴气渐长而阳气渐衰,至黄昏时分又大致相当,形成下面为阳上面为阴的格局,这就是少阴,等夜幕完全降临的子夜时分,阴气最盛,所以称之为太阴,此后阴衰阳长,至凌晨时阴阳又大致相当,如此周而复始,日复一日。当然用春夏秋冬也同样可以说明这一现象。

易经学习教程(二)
易经学习教程(二)

四象再进一步相互交合,便产生了我们学习的重点内容:八卦。易经认为,天地万物生成之后,可以将万物粗略地分为八大分类,这八个分类是:天、地、水、火、泽、山、风、雷。大自然的一切变化,都是由于这八种东西在相互作用而推动。易经将这八种现象重新命名为:

乾(qián)、坤(kūn)、坎(kǎn)、离(lí)、兑(duì)、艮(gèn)、巽(xùn)、震(zhèn)

二、阴阳的原理

易经认为万事万物归根结底都是由于阴阳相互作用而形成的,这一点在物理学上也同样得到了证明。物理学认为任何物质都是由分子组成,而分子又是由比它更小的原子按一定的结构组成。原子是组成物质的基本单位。原子是由带正电荷的原子核和带负电荷的电子组成,看起来一个不带电荷的物体,实际上都或多或少对外表现出电荷,只是影响力的范围有限。

例如一个氢原子是由带一个正电荷的原子核和带一个负电荷的电子组成,许多人以为正负相抵,对外表现应该为中性。其实不然,在一定的范围内,因离外围的电子较近,所以呈现的是负电性,而达到一定范围之后,又会呈现弱的正电性。这个道理很简单,当嫦娥三号接近月球时,当然是受月球的引力更多些,如果飞船继续向外层空间飞行,则仍然是受地球的引力更大,当超出一定距离之后,则又变为太阳引力大于地球的引力。当很多原子组合成分子,很多分子组合成其它结构(如细胞等),对外或多或少都会有电荷的呈现,并随着距离的远近而电性不一。

任何宏观物体都有引力,物理学上称之为万有引力。这个引力的本质还是众多电荷组合在一起所表现出来的力量。除了万有引力还有磁场引力,其本质仍然是由电荷所引起,磁场是电的另一种表现形式,有电就有磁的存在,同样有磁也一定有电的存在,二者不可分,也是可以相互转化的。不仅万有引力、磁场是电的作用,人的性格、人的思想也是这一电的影响而产生的。总之,万事万物的变化发展都离不开电的作用,而这个电的正负在易经上就是阴阳。

宏观上的万物是由阴阳的相互作用而形成,微观也是如此。一个电子的内部并不是只有负电荷而没有正电荷,而是正负电荷仍然相等,只不过是表现出来为负电荷。原子核是由带正电荷的质子和中性的中子所组成。质子和中子的内部也同样是正负电荷相同,只不过是质子表现出来为正电荷,而中子表现出来为相对中性,但也不是绝对中性。

易经研究万事万物的方法和物理学是不一样的,物理学重点放在找出物与物之间的差别,而易经的重点是找出物与物之间的共性。所以物理学的正负可以说成易经中的阴阳,但易经中的阴阳不仅仅是物理学中的正负。易经认为一切相互对立统一的东西都可以看着阴阳,例如热为阳则冷为阴,南为阳则北为阴,高为阳则低为阴,动为阳则静为阴,刚为阳则柔为阴,男为阳则女为阴。

由此看来可以这样说,物理学是将对事物的研究不断细化,所以越来越复杂;而易经是对事物不断归纳总结,将复杂的事物归类为简单的八卦。不管是物理学也好,易经的学问也好,都是找出事物之间的规律,有了规律就可以预测事物的发展,所以说易经本身决不是迷信,不是伪科学,但不可否认被许多江湖术士参杂了部分不科学的内容。

我们研究宏观的星球变化规律可以促进我们对微观领域的分子、原子、电子等的研究,反过来也是,从电子、核物理的研究同样推动了对星球规律的研究。研究易经和研究物理学同样也有相互促进的作用。事实上,二进制的发明就是莱布尼茨根据对周易的研究而发明的。所以小雅希望,科学工作者和易经从事者不要相互恶意攻击、贬低对方。

易经学习教程(二)

上面所列举的冷热、南北、高低、动静、刚柔、男女等,可不可以反过来定义,即冷为阳而热为阴,北为阳而南为阴,低为阳而高为阴,静为阳而动为阴,柔为阳而刚为阴,男为阴而女为阳?答案是不能。因为易经中的阴阳还有其它一些属性,即阳主动而阴主静,阳主刚而阴主柔,动则易于创新,同时易疲倦,所谓利益与风险同在,倦则思归、思静;静则能养、能藏,养则蓄,蓄则精力充沛,必然蠢蠢欲动。所以阳极则阴生,阴极则阳生。

热则易动而冷则易藏,所以热为阳而冷为阴,南方热而北方冷,所以南为阳而北为阴,高处的物体易落下,而低处的东西没有外力的作用不会飞到高处,所以高为阳而低为阴,男好动而女好静,此为天性,当然男为阳而女为阴。如果是在南半球,当然也可以南为阴而北为阳;如果是性格如火的女强人与柔弱丈夫之间,也可以女为阳而男为阴。易经研究的是共性,所以用易经来预测,也会有不准的地方,这并不奇怪,片面地夸大易经的功能是不可取的。

四象中的太阳和太阴,有人说就是每天出现的太阳和月亮,这是不正确的。太阳和月亮可以用来象征性地表示四象中的太阳和太阴,不能反过来说,四象的太阳太阴就是天空中的太阳月亮。前面说过的中午和子夜也是四象的太阳和太阴,夏至和冬至也可以表示为太阳和太阴,这时春分表示少阳,秋分表示少阴。少阳、少阴虽然都是阴阳平衡的状态,但少阳是由阴转阳的过程,而少阴则是由阳转阴的过程。

三、八卦排列

用四象来表示万物,即使在有巢氏、燧人氏的远古时代仍然是过于简单,到了伏羲时代,在四象的基础上演化出了八卦的内容。八卦最初是用大自然中的最常见的八种现象来表示,这就是:天、地、水、火、泽、山、风、雷。那么为什么伏羲又将八卦命名为:乾、坤、坎、离、兑、艮、巽、震?这道理很简单,正负不能代表阴阳,因为正负是具体的电荷的属性,而阴阳是万物的属性。同样,天地水火泽山风雷是万物中有形有名的东西,而我们易经中需要的是抽象的名称。在表示大自然时,固然可以用天地水火泽山风雷来表示乾坤坎离兑艮巽震,但在其它情况下却不一定恰当,比如表示家庭时,父母表示乾坤、长男长女表示震巽、中男中女坎离、少男少女表示艮兑。

八卦是四象的进一步演化生成出来的,阴阳是宇宙万物的根本,而四象是天地间的四大现象,故名之为“四象”,再加上天地间人的因素,就构成了三才天地人,天地人各有阴阳,这就产生了八种排列组合。这八种组合就形成了八个卦。易经中用“易经学习教程(二)”表示阳,而用“易经学习教程(二)”表示阴,于是,太阳太阴分别表示为:“易经学习教程(二)”、“易经学习教程(二)”,少阳少阴则表示为:“易经学习教程(二) ”、“易经学习教程(二)”。因人居天地之中,所以在四象的符号中间分别加上阴、阳就成了八卦:离 、坤 、艮 、震 、乾 、坎 、巽 、兑 。

古人为了方便我们记忆,已经为大家编制了形象生动的口诀,大家只要记住口诀就能记住卦象,但更重要的是记住顺序的读音。箭头所示的一对卦象,其阴阳正好相反,我们将这样的一对卦称为“反卦”,也叫“错卦”。另外,上下颠倒的2个卦为“覆卦”,也叫“综卦”,震和艮、巽和兑是2组综卦。

易经学习教程(二)

伏羲所画八卦本没有排列顺序,后人在实际应用的过程中编制了顺序,并赋于了相应的“数”,我们称之为“八卦数”,这个顺序就是1.乾、2.兑、3.离、4.震、5.巽、6.坎、7.艮、8坤,在此基础之上又绘制了八卦图,为了避免与文王的周易八卦混淆,一般称这个顺序为“伏羲八卦”或“先天八卦”,而将周易中的八卦称之为“后天八卦”或“文王八卦”。先天八卦顺序数形成的原因如下图所示:

易经学习教程(二)

易经学习教程(二)

需要说明的是后人将先天八卦数绘制成一个圆图,由于受后天八卦图的影响,几乎所有的书上都将这个图配备了方位,认为乾南坤北、离东坎西,这实在是一个错误。先天八卦顺序在将来的预测中,一般用之起卦,而应用时则全部使用的是后天八卦的方位,许多人不明其中原因。

之所以称其为“先天”是因为这个图演示的是万物形成的过程,所以在起卦时只能用先天数,不能用后天数。当卦建立之后,表示事物已经形成,预测其以后的发展,则这时必须使用后天八卦。所以易经预测就是用易经的方法来演示事物的发展,从而把握其中的规律。关于什么是起卦、起卦的方法以等问题将在后面的章节介绍。先天八卦没有方位也是同样的道理,因为事物尚未形成,方位则无从谈起,只有事物形成之后,才有方位之说,所以只有后天八卦才有方位。

四、八卦的意思

学习了八卦的卦名、卦象、顺序数及先天八卦图之后,我们有必要来理解一下八个卦的意思以及八卦之间的相互关系。这些内容主要在《说卦传》中,是初学者首先要学的内容。

“昔者,圣人之作易也,幽赞于神明而生蓍。参(sān)天两地而倚数;观变于阴阳,而立卦;发挥于刚柔,而生爻;和顺于道德,而理于义;穷理尽性,以至于命。”远古的圣人对大自然的许多神奇的造化虽不了解却赞叹不已,于是就用蓍草来仿效天地演绎万物,从而得到各种数据,观察其中的阴阳变化并记录这种现象,由于卦是由爻组成,事物发展变化都体现在爻上,通过爻的变化就可以遵从道德礼仪,按事物的客观规律来行事。

上面讲述了八卦的形成原因和目的,那么这八个卦之间有什么关系呢?“天地定位,山泽通气,雷风相薄,水火不相射,八卦相错,数往者顺,知来者逆;是故,易逆数也。”这一段内容古人说法各有不同,小雅认为这是用大自然的现象来粗略地解释八卦的特性。乾坤为其它六卦的父母卦,相当于天地,天地确定之后万物始成。山和泽都是以地为根,阳秀于阴而为艮易经学习教程(二),阴秀于阳而为兑易经学习教程(二),故有山泽通气于地。外阴内阳而为坎易经学习教程(二),外阳内阴而为离易经学习教程(二),水火各不相容。风雷皆源自于天,皆有通天彻地之能,阴极一阳生而成震易经学习教程(二),雷响则电生,阳极一阴生而成巽易经学习教程(二),风起则雨降,雨水与电火相迫。八个卦相互交叉作用,按这个规律发展则为顺,利用这个规律来改变事物的发展则为逆,易经的关键作用在利用规律来避凶化吉。

各卦自身又有什么特点呢?下面两段一起来看比较容易理解。“雷以动之,风以散之,雨以润之,日以烜之,艮以止之,兑以说之,乾以君之,坤以藏之。”“乾,健也;坤,顺也; 震,动也;巽,入也;坎,陷也;离,丽也;艮,止也;兑,说也。”雷的最大特点就是让坤所藏的万物动起来,所以春雷一声万物复苏。风的最大特点是飘散,无处不入,弥满于天地之间。水的作用是滋润万物,使万物运送养分,同时水多了之后,就成了坎坷。火的作用是照亮一切,使万物绚丽多彩。山的最大特点是阻止一切通行。泽的特点是喜悦,因泽中有水,而水利万物故有喜悦之意。乾为父、为主宰,有旺盛永久的动力。坤为母、因其柔顺而包藏万物,万物化育而主生。

上面是八卦在大方面的特性,在具体预测过程中,又有许多为同的象征,较为明显的是在人伦家庭方面,乾坤为父母,由母性得第一索阳爻而象征长男,得第二索阳爻而象征中男,得第三索阳爻而象征少男。同样原理,由父性得第一索阴爻而象征长女,得第二索阴爻而象征中女,得第三索阴爻而象征少女。从这六个卦象可以看出,阳卦多阴,阴卦多阳。

在人体方面,“乾为首,坤为腹,震为足,巽为股,坎为耳,离为目,艮为手,兑为口。”在动物方面,“乾为马,坤为61阅读阅读。劝学网网址为http://www.quanxue.cn

本文标题:易经入门学习教程-经典MPLS学习教程
本文地址: http://www.61k.com/1093827.html

61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1