第四章 sql 和 pl/sql

151
第第第 SQL 第 PL/SQL SQL PL/SQL

Upload: ethan-ballard

Post on 03-Jan-2016

94 views

Category:

Documents


0 download

DESCRIPTION

第四章 SQL 和 PL/SQL. SQL. PL/SQL. DDL 数据定义语言:包括一些支持定义或建立数据库对象(如表、索引、序列或视图)的语句。 Create、alter、drop DML 数据操纵语言:包括允许对数据库进行处理或操纵的语句。 Select、insert、delete、update. 创建表. 格式: create table 表名 (列名1 数据类型 【约束】, 列名2 数据类型 【约束】, 列名3 数据类型 【约束】 );. 数据类型 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第四章  SQL 和 PL/SQL

第四章 SQL 和 PL/SQL

SQL

PL/SQL

Page 2: 第四章  SQL 和 PL/SQL

DDL 数据定义语言:包括一些支持定义或建立数据库对象(如表、索引、序列或视图)的语句。 Create 、 alter 、 drop

DML 数据操纵语言:包括允许对数据库进行处理或操纵的语句。 Select 、 insert 、 delete 、 update

Page 3: 第四章  SQL 和 PL/SQL

创建表

格式: create table 表名 ( 列名 1 数据类型 【约束】, 列名 2 数据类型 【约束】, 列名 3 数据类型 【约束】 ) ;

Page 4: 第四章  SQL 和 PL/SQL

数据类型 varchar2(size) 存放可变长字符数据 char(size) 存放定长字符数据 number(l,d) 存放数值型数据, l 代表总位

数, d 代表小数点后的位数 blob 二进制大对象 raw(size) 纯二进制数据 date 存放日期 long 存放可变长字符数据

Page 5: 第四章  SQL 和 PL/SQL

Number

number : 允许在小数点左边或右边输入任何个数的数字

Number(5) : 允许在小数点左边不多于 5 位数,如果任何数字被插入到小数点的右边,该数字将被 4 舍 5 入。

Number(5,2) :允许总数不超过 5 位数,其中2 位在小数点右边, 3 位在左边。

Page 6: 第四章  SQL 和 PL/SQL

约束 null/not null

primary key 要求进入该列的值是惟一的,且不为 null

foreign key

unique 防止重复值进入该列,但允许为 null

check 限制属性列的输入值

Page 7: 第四章  SQL 和 PL/SQL

命名约束与未命名约束

在建立或修改表时,用户可明确给出约束的名称。否则约束名将由 RDBMS 内部命名。由用户命名的约束称为命名约束; RDBMS 命名的约束由开发商决定,称未命名约束。

命名约束的格式: constraint 约束名 约束命名规定:表名-列名-后缀

Page 8: 第四章  SQL 和 PL/SQL

例 1 :用以下属性及设定建立表 calling-card.

属性:公司名 company-name 、卡号 card-number 、初值 starting-value 、余额 value-left 、初始密码 pin-number 。

设定:属性 company-name 可具有多达 25 个字符,属性 value-left 及 starting-value 用元及分来度量。属性 card-number 属性定义为主码;将 pin-number 属性定义为惟一码。

请用命名约束来书写 create table 。

Page 9: 第四章  SQL 和 PL/SQL

Create table calling-card

(company-name varchar2(25),

card-number varchar2(20) constraint

calling-card-card-number-pk primary key,

starting-value number(5,2),

value-left number(5,2),

pin-number char(12) constraint

calling-card-pin-number-u unique

);

Page 10: 第四章  SQL 和 PL/SQL

2. 描述表结构 当一个表建立后,可能需要确定表的名称、

数据类型及组成表的属性的一些约束。 使用: describe 表名; 或 desc 表名; 如: desc calling-card;

Page 11: 第四章  SQL 和 PL/SQL

3. 插入行

使用 insert into 语句,一条语句只允许一次插入一行。

insert into 表名(列 1 ,列 2 ,……列N )

values ( 值 1 ,值 2…… 值 N);

如果写在 values 子句中的数据项的顺序与create table 命令中表的属性顺序相同,则不用在 insert into 子句中写出列名。

Page 12: 第四章  SQL 和 PL/SQL

例 1 :将下列数据插入 calling-card 表移动 1237096435 50.00 12.45 987234569871联通 5497443544 100.00 11.37 433809835833

Insert into calling-card(company-name,card-number,starting-value,value-left,pin-number)

values(‘ 移动’,‘ 1237096435’ , 15.00 ,11.37 ,‘ 987234569871’) ;

Insert into calling-card(company-name,card-number,starting-value,value-left,pin-number)

values(‘ 联通 ’,‘ 5497443544’ , 100.00 ,11.37 ,‘ 433809835833’) ;

注:所有的字符数据都放再单引号内。

Page 13: 第四章  SQL 和 PL/SQL

练习 1 :利用下面给出的信息,写出 programmer 表的create table 指令。假设该表的属性满足下面所示的条件。

属性名 描述 / 数据类型 / 约束Empno 程序员的惟一 id ,最长为 3 个字符Project 程序员所参与的项目,最长为 3 个字符Taskno 该项目相关的任务号,为数值列,最多 2

位数name 雇员的姓名,最长为 25 个字符Hire-date 雇员的雇佣日期,日期数据类型Language 程序员使用的编程语言,最长 15 个字符

Page 14: 第四章  SQL 和 PL/SQL

Drop table programmer cascade constraints;

Create table programmer

(empno varchar2(3) primary key,

name varchar2(25) not null,

hiredate date,

project varchar2(3),

language varchar2(15),

taskno number(2)

);

Page 15: 第四章  SQL 和 PL/SQL

用下列数据填充 programmer 表。

empno Name hiredate project Language Taskno

201 John 1/1/95 NPR VB 52

789 richard 08/31/98 RNC JAVA 11

134 Andy 08/15/94 NITTS C++ 89

Page 16: 第四章  SQL 和 PL/SQL

Insert into programmer (empno,name,hire- date,project,language,tashno)

values(‘201’,’John’,’1-JAN-95’,’NPR’,’VB’,52);

注:在缺省设置中日期表示形式为:“ DD-MM-YY”, 其中 DD 是某月的任一天( 1 ~31 ), MM 是月份的前三个字母的缩写( JAN,FEB,DEC… ) ,YY 是年的后两位数字。

Page 17: 第四章  SQL 和 PL/SQL

练习 2 :写一个脚本,为零售店 Waves-R-US 建立一个产品表 product 。该表属性如下所示。如果需要的话可使用命令约束,并证实建立的表是正确的。

属性名 说明ID 惟一的产品标识,最长为 5 个字符。需要

Name 产品名,最长为 25 个字符。需要

Discount precentage

对优选客户的价格折扣百分率,最多 1 位数

Price 产品的零售价,总共 6 位数字,其中带 2 位小数

Page 18: 第四章  SQL 和 PL/SQL

Create table product

( id varchar2(5) constraint product-id-pk primary key,

Name varchar2(25)

constraint product-name-nn not null,

Discount-precentage number(1),

Price number(6,2)

) ;为了证实所建立的表是正确的,需要使用

describe product 命令确定它的结构。Describe product;

Page 19: 第四章  SQL 和 PL/SQL

4.Commit 及 rollback 命令 对一个表进行 insert 、 update 或 delete 操作后,用户可使用 commit 语句使所做的变更永久性的记录到数据库中。

一般大部分数据库处理完一个 DDL 语句后发出一个隐式的 commit 语句。

假设对表的改变(插入、更新或删除)尚未提交,用户可通过 rollback 语句取消对表所做的全部中间变化。

Page 20: 第四章  SQL 和 PL/SQL

Savepoint 命令

用户希望及时回到某一个特定点(称为保留点),取消保留点之后对表的改变可使用 savepoint 命令。

savepoint 保留点名; rollback 保留点名 或 rollback to savepoint 保留点名

Page 21: 第四章  SQL 和 PL/SQL

A B C

a1 b1 c1

a2 b2 c2

A B C

a1 b1 c1

a2 b2 c2

a3 b3 c3

Savepoint A Savepoint B

在表中插入一行

A B C

a2 b2 c2

a3 b3 c3

在表中删除第一行

Savepoint C

Rollback to savepoint A

Page 22: 第四章  SQL 和 PL/SQL

5.select 语句 select 列 1 ,列 2…… 列 N from 表 1 ,……表 N 【 where 条件】 【 order by 列 1[asc|desc][ 列 2[asc|desc]

…] 】 ;

Where 子句的比较运算符:=, <>, <, <=, > , >=查询表中所有列信息: select * from 表名;

Page 23: 第四章  SQL 和 PL/SQL

例 1 :使用 calling-card 表查询移动公司发行的电话卡的卡号和初值。查询显示按卡号从小到大排列。

select card-number, starting-value

from calling-card

where company-name=‘ 移动’ order by card-number [asc] ;

Page 24: 第四章  SQL 和 PL/SQL

练习 1 :1. 使用 employee 表显示在会计部门工作的

所有雇员的姓名及职务。

2.按雇员姓名的字母顺序显示上一个查询结果。

ID NAME DEPT TITLE

100 Smith Sales Clerk

200 John Marketing Clerk

300 Martin Accounting Clerk

400 Bell Accounting Sr.accountant

Page 25: 第四章  SQL 和 PL/SQL

1. Select name, title

from employee

where dept=‘Accounting’;

2. Select name, title

from employee

where dept=‘Accounting’

order by name;

Page 26: 第四章  SQL 和 PL/SQL

表行的更新update 表命令

Update 表名 set 列 1=新值 1 ,……列 N=新值

N

where 条件;

Page 27: 第四章  SQL 和 PL/SQL

例 1 :将卡号为 1237096435 的电话卡的公司名改为联通。

update calling-card

set company-name=‘ 联通’ where card-number=‘1237096435’;

Page 28: 第四章  SQL 和 PL/SQL

Delete 命令Delete from 表名

where 条件;…………删除指定行

Delete 表名; …………删除表中所有数据

例 1 :删除 calling-card 表中联通的所有电话卡记录。

Delete from calling-card where company-name=‘ 联通’ ;

Page 29: 第四章  SQL 和 PL/SQL

Drop table 命令Drop table 命令可从数据库中删除一个表及其中所有数据。

drop table 表名 【 cascade constraints 】 ;

如果想要删除的某个表具有参照完整性约束时,使用可选的 cascade constraints 子句。

Page 30: 第四章  SQL 和 PL/SQL

练习 1 : 写一个脚本,创建一个 emp 表,该表的属性如下:

列名 描述 / 数据类型Id 每个雇员惟一的标识号,最长为 3 个字符Name 雇员的姓名,最长为 20 个字符Userid 雇员登陆系统的 ID ,最长为 8 个字符Start-date 雇员开始在公司工作的日期Manager-id 雇员经理的 ID ,最长为 3 个字符Title 雇员在公司里的职务,最长为 25 个字符Dept-id 雇员的部门 ID ,最长为 3 个字符Salary 雇员的工资,共 11 位数,包括 2 位小数Commision 雇员赢得的佣金百分率,共 4 位数,包括 2 位小

Page 31: 第四章  SQL 和 PL/SQL

1.根据 emp 表,列出所有雇员的姓名、 ID及职务 , 要求不同职务按字母顺序排列,对相同职务的雇员,按其姓名的降序排列。

2. 给在部门 41工作的所有雇员提高工资 200 元。对结果加以验证。万一出错,确保所有的变化均能取消。如果操作有误,用户如何取消这些变化。

Page 32: 第四章  SQL 和 PL/SQL

1. Select name, id,title From emp Order by title , name desc;2. Savepoint before_update; update emp set salary=salary+200 where dept_id=’41’;通过查询可对改变是否正确加以验证: select name salary from emp where dept_id=’41’;如果更新不正确,用户可通过以下命令取消这些改变。 rollback to savepoint before_update;

Page 33: 第四章  SQL 和 PL/SQL

SQL 中关系运算符的执行使用 distinct取消重复的行

select [all|distinct] 列 1 ,列 2…… 列 N from 表 1 ,……表 N 【 where 条件】 【 order by 列 1[asc|desc][ 列 2[asc|desc]…] 】 ;

例:在 emp 表中,有多少不同的职务? select distinct title from emp;

Page 34: 第四章  SQL 和 PL/SQL

连接运算符的执行 连接( join )运算允许我们将来自两个或多

个表的数据形成一个单一表。主要的连接类型: 等值连接:两表通过共同的等值列而连接 自连接:一个表与其本身的连接 外连接:两个表之间的连接,决定一个表的

所有行在另一表中没有匹配的元组。

Page 35: 第四章  SQL 和 PL/SQL

等值连接 select 表 1. 列 1 ,表 1. 列 2…, 表 2. 列 1 ,…

表 2. 列 N

from 表 1 ,表 2

where 表 1. 列名=表 2. 列名;

如果在两个表中没有相同的列,则没有必要在列名前加表名。

Page 36: 第四章  SQL 和 PL/SQL

Emp 表:列名 描述 / 数据类型

Id 每个雇员惟一的标识号,最长为 3 个字符Name 雇员的姓名,最长为 20 个字符Userid 雇员登陆系统的 ID ,最长为 8 个字符Start-date 雇员开始在公司工作的日期Manager-id 雇员经理的 ID ,最长为 3 个字符Title 雇员在公司里的职务,最长为 25 个字符Dept-id 雇员的部门 ID ,最长为 3 个字符Salary 雇员的工资,共 11 位数,包括 2 位小数Commision 雇员赢得的佣金百分率,共 4 位数,包括 2 位小

Page 37: 第四章  SQL 和 PL/SQL

Dept 表:

列名 描述 / 数据类型

Id 每个部门惟一的标识号,最长为 3 个字符

Name 部门名称,最长为 20 个字符

Region_id 部门所在的区域 id ,最长为 3 个字符

Page 38: 第四章  SQL 和 PL/SQL

例 1 :查询所有雇员的姓名及所在部门名称。 Select emp.name,dept.name

From emp,dept

Where emp.dept_id=dept.id ;使用表别名: select A.name , B.name

from emp A,dept B

where A.dept_id=B.id ;

Page 39: 第四章  SQL 和 PL/SQL

自连接自连接是一个表与其自身的连接

例 1 :显示每一个雇员的名字及他或她的管理者的名字。

select E.name as “employee”,

M.name as “manager”

from emp E,emp M

where M.id=E.manager_Id

Page 40: 第四章  SQL 和 PL/SQL

外连接假设有两个表的连接,有时我们想知道不满足其中一个表指定条件的另一个表的行。例如,我们想知道还没有管理者的雇员。

select 表 1. 列 1 ,表 1. 列 2…, 表 2. 列 1 ,…表 2. 列 N

from 表 1 ,表 2

where 表 1. 列名(+)=表 2. 列名; 用于计算在表 1 中所有与表 2 不匹配的行的外连接 select 表 1. 列 1 ,表 1. 列 2…, 表 2. 列 1 ,…表 2. 列 N

from 表 1 ,表 2

where 表 1. 列名=表 2. 列名(+); 用于计算在表 2 中所有与表 1 不匹配的行的外连接

Page 41: 第四章  SQL 和 PL/SQL

例:列出无管理者的所有雇员。 select E.name as “employee”,

M.name as “manager”

from emp E,emp M

where M.id (+) =E.manager_Id

Page 42: 第四章  SQL 和 PL/SQL

练习 1 :1. 在 dept 表和 region 表中查询所有部门及它们所在的区域名。

2.显示所有销售代表及他们的客户的姓名。3.显示目前还没有指定销售代表的客户。

Page 43: 第四章  SQL 和 PL/SQL

Customer 表:

列名 描述 / 数据类型Id 客户惟一的标识号,最长为 3 个字符Name 客户名,最长为 20 个字符Address 客户的地址,最长为 20 个字符Zip_code 客户的邮政编码,最长为 15 个字符Phone 客户的电话号码,最长为 20 个字符Credit_rating 客户的信誉等级,最长为 9 个字符Sales_rep_id 客户的销售代表,最长为 3 个字符Region_id 客户居住的国家所在的区域,最长为

3 个字符

Page 44: 第四章  SQL 和 PL/SQL

Emp 表:列名 描述 / 数据类型

Id 每个雇员惟一的标识号,最长为 3 个字符Name 雇员的姓名,最长为 20 个字符Userid 雇员登陆系统的 ID ,最长为 8 个字符Start-date 雇员开始在公司工作的日期Manager-id 雇员经理的 ID ,最长为 3 个字符Title 雇员在公司里的职务,最长为 25 个字符Dept-id 雇员的部门 ID ,最长为 3 个字符Salary 雇员的工资,共 11 位数,包括 2 位小数Commision 雇员赢得的佣金百分率,共 4 位数,包括 2 位小

Page 45: 第四章  SQL 和 PL/SQL

1. Select D.name as “department” ,R.name as “region”

from dept D, region R where D.region_id = R.id ;2. Select E.name as “sales reps”, C.name as “customers” from emp E, customer C where C.sales_rep_id=E.id ;3. Select C.name as “customers” , E.name

as “sales reps” from emp E, customer C where C.sales_rep_id=E.id(+) ;

Page 46: 第四章  SQL 和 PL/SQL

建立外码create table 表名 ( 列名 1 数据类型 【 constraint 约束

名】 references 参照表名(列名), 列名 2 数据类型 【约束】, 列名 3 数据类型 【约束】 ) ;

Page 47: 第四章  SQL 和 PL/SQL

Emp 表:列名 描述 / 数据类型

Id 每个雇员惟一的标识号,最长为 3 个字符Name 雇员的姓名,最长为 20 个字符Userid 雇员登陆系统的 ID ,最长为 8 个字符Start-date 雇员开始在公司工作的日期Manager-id 雇员经理的 ID ,最长为 3 个字符Title 雇员在公司里的职务,最长为 25 个字符Dept-id 雇员的部门 ID ,最长为 3 个字符Salary 雇员的工资,共 11 位数,包括 2 位小数Commision 雇员赢得的佣金百分率,共 4 位数,包括 2 位小

Page 48: 第四章  SQL 和 PL/SQL

Dept 表:列名 描述 / 数据类型

Id 每个部门惟一的标识号,最长为 3 个字符

Name 部门名称,最长为 20 个字符

Region_id 部门所在的区域 id ,最长为 3 个字符

例 1 :根据上面的信息,建立 emp 表。定义dept_Id 为 FK, 且该 FK 参照另一个 dept 表的 id 。

Page 49: 第四章  SQL 和 PL/SQL

Create table emp( id varchar2(3) , name varchar2(20) , userid varchar2(8) , start_date date, manager_id varchar2(3), title varchar2(25), dept_id varchar2(3) references dept(id), salary number(11,2) commision number(4,2)) ;在加上外码约束时,必须确定 dept 表中属性 id已经被

定义为 PK 。

Page 50: 第四章  SQL 和 PL/SQL

在一个已存在的表中定义外码使用 alter table 命令:

alter table 表名 add 【 constraint 约束名】 foreign key( 列

名 )

references 参照表名(列名);

Page 51: 第四章  SQL 和 PL/SQL

例:使用 dept 表,将一个 FK加至此表中,使属性 region_id 参照 region 表的属性 id 。

Region 表:

alter table dept

add foreign key(region_id)

references region(id);

列名 描述 / 数据类型Id 每个区域惟一的标志号,最长为 3 个字符Name 每个区域惟一的名称,最长为 20 个字符

Page 52: 第四章  SQL 和 PL/SQL

在一个已存在的表中定义主码

使用 alter table 命令:

alter table 表名 add 【 constraint 约束名】 primary key( 列 1 [ ,列 2…] );

Page 53: 第四章  SQL 和 PL/SQL

例:在 dept 表中, id 及 region_id 的组合必须是惟一的。这一点确保了在地区中部门的惟一性。

alter table dept

add primary key (id, region_id);

Page 54: 第四章  SQL 和 PL/SQL

使用 check 约束限制属性列的输入值

Page 55: 第四章  SQL 和 PL/SQL

例:在 customer 表中,客户的信誉等级只能取excellent 、 good 或 poor 值。

create table customer

(id varchar2(3),

name varchar2(20),

address varchar2(20),

zip_code varchar2(15),

phone varchar2(20),

credit_rating varchar2(9) constraint customer_credit_rating_ck check(credit_rating IN (‘excellent’,’good’,’poor’)),

sales_rep_id varchar2(3),

region_id varchar2(3)

) ;

Page 56: 第四章  SQL 和 PL/SQL

例 2 :假设我们正在建立一个 department 表,其中,部门数大于 10 ,小于 50 。写出check 约束,以确保插入表中的每个部门数都在这个范围内。

create table department(

name varchar2(15)

constraint department_name_nn not null,

location varchar2(20),

deptnum number check (deptnum

between 10 and 50 ));

Page 57: 第四章  SQL 和 PL/SQL

对已存在的表添加属性列Alter table 表名

add 新列名 数据类型【约束】;

例 1 :在 department 表中,加入一个名为manager_name 的新列。假设该列可长达 25 个字符。

alter table department

add manager_name varchar2(25);

Page 58: 第四章  SQL 和 PL/SQL

对已存在的表修改属性列Alter table 表名

modify 列名 【数据类型 / 约束】 ;

例 1 :在 department 表中,增加 name 列大小。

alter table department

modify name varchar2(45);

Page 59: 第四章  SQL 和 PL/SQL

从表中删除约束

Alter table 表名 drop primary key 【 cascade 】 ;

Alter table 表名 drop unique 【 cascade 】 ;

Alter table 表名 drop 约束名【 cascade 】 ;

Page 60: 第四章  SQL 和 PL/SQL

从表中删除列

Alter table 表名 drop column 列名 ;

Page 61: 第四章  SQL 和 PL/SQL

例 1 :删除 department 表中 name 属性的not null 约束。

alter table department

drop constraint department_name_nn;

Page 62: 第四章  SQL 和 PL/SQL

练习:1. 将新列 performance加至 emp 表。该列的

允许值为‘ satisfactory’ ’、 excellent’ ’、 unsatisfactory’ 。证实该列被正确地加入了。

2. 将 customer 表中的属性 address 长度从 20个字符增加到 25 个字符。

3. 删除添加到 emp 表中的 check 约束。

Page 63: 第四章  SQL 和 PL/SQL

1. Alter table emp

add performance varchar2(15) constraint emp_performance_ck check ( performance in (‘satisfactory’,’excellent’,’unsatisfactory’));

2. Alter table customer

modify address varchar2(25 ) ;

3. Alter table emp

drop constraint emp_performance_ck;

Page 64: 第四章  SQL 和 PL/SQL

布尔运算符和字符匹配

1.布尔运算符:AND逻辑运算符

select 列名 from 表名 where 条件 1 AND 条件 2 ;

Page 65: 第四章  SQL 和 PL/SQL

例:列出 customer 表中具有 excellent 信誉等级、邮政编码为 22809 的所有客户的名称。

select name

from customer

where credit_rating=‘excellect’ and zip_code=‘22809’

/

Page 66: 第四章  SQL 和 PL/SQL

OR逻辑运算符 select 列名 from 表名 where 条件 1 OR 条件 2 ;

例:列出 customer 表中具有 excellent 或good 信誉等级的所有客户。Select nameFrom customerWhere credit_rating=‘excellect’ or credit_rating=‘good’/

Page 67: 第四章  SQL 和 PL/SQL

NOT逻辑运算符 select 列名 from 表名 where NOT 条件;

例:列出 customer 表中邮政编码不为 22808的全部客户名、邮政编码及销售代表号。

Select name, zip_code, sales_rep_idFrom customerWhere not zip_code=‘22808’/

Page 68: 第四章  SQL 和 PL/SQL

德 .摩根定律NOT(p AND q) NOT p OR NOT q

NOT(p OR q) NOT p AND NOT q

NOT(NOT p) p

例:列出 customer 表中邮政编码不为 22808 同时也不与 sales_rep_id 为 14 相关的销售代表相关的所有客户名、邮政编码及销售代表。

Page 69: 第四章  SQL 和 PL/SQL

Select name, zip_code, sales_rep_id

from customer

where not zip_code =‘22808’ and not sales_rep_id =’14’;

或: Select name, zip_code, sales_rep_id

from customer

where not (zip_code=‘22808’ or sales_rep_id =’14’)

/

Page 70: 第四章  SQL 和 PL/SQL

布尔运算的优先级优先级 运算符

1 ()2 NOT p

3 p AND q

4 p OR q

例:检索邮政编码为 22808 或 22809, 并且具有极好信誉等级的客户。

Page 71: 第四章  SQL 和 PL/SQL

Select name, zip_code , credit_rating

from customer

where (zip_code =‘22808’ or zip_code=‘22809’) and credit_rating=‘excellent’;

Page 72: 第四章  SQL 和 PL/SQL

2. 字符匹配—— LIKE 子句及通配符百分号(%)通配符:代表零个或多个字符的

字符串。例 1: 在 emp 表中查询姓名以字母 B 开头的所

有的雇员的姓名。 select name

from emp

where name like ‘B%’

/

Page 73: 第四章  SQL 和 PL/SQL

例 2 :列出地址中有 High 的客户的名称、地址。

select name , address

from customer

where address like ‘%High%’

/

Page 74: 第四章  SQL 和 PL/SQL

下划线( _ )通配符:代表任意一个字符。例:在 emp 表中查询姓名以 M 开始,且名字

正好为 5 个字母的所有雇员的姓名。 select name

from emp

where name like ‘M_ _ _ _’

/

注意:若要匹配通配符‘%’或‘ _’ 本身可使用换码字符“ \” 。

Page 75: 第四章  SQL 和 PL/SQL

Between运算符Select 列名From 表名Where 列名 between 低值 and 高值 ;

例 1 :列出客户 ID 在 303 及 306之间的客户的 ID 、名字及电话号码。

select id, name, phone

from customer

where id between ‘303’ and ‘306’;

Page 76: 第四章  SQL 和 PL/SQL

例 2 :列出客户的 ID 、姓名及电话号码,要求客户名字的开头是从 A 到 G之间的字母。

select id , name, phone

from customer

where name between ‘A’ and ‘H’;

Page 77: 第四章  SQL 和 PL/SQL

IN运算符Select 列名From 表名Where 列名 in ( 值 1 ,值 2 ,…值 n) ;

例 1 :查询客户 ID 为 303 、 305 、 403 及 406 的客户的 ID 、名字及电话号码。

select id, name, phone from customer where id in(‘303’,’305’,’403’,’406’);

Page 78: 第四章  SQL 和 PL/SQL

例 2 :查询具有 excellent 或 poor 信誉等级的客户名字及信誉等级的 SQL 语句。

select name, credit_rating

from customer

where credit_rating in(‘excellent’,’poor’)

/

Page 79: 第四章  SQL 和 PL/SQL

练习:使用 emp 、 customer 、 dept 、 region表

1. 显示在部门 31 及在部门 41工作的雇员的姓名、部门id 及工资。

2. 查询经理 ID 为 1 、 2 或 null 的所有雇员的姓名、职务及其经理 ID ,将结果按职务、姓名的字母顺序排序。

3. 显示不在部门 31 或 41工作,但工资高于 2000 元的所有雇员的姓名、部门 id 及工资。

4. 查询在部门 41工作,是 stock clerk 或 warehouse manager 的所有雇员的姓名、职位及部门 ID 。

5. 查询所有具有 poor 信誉等级的客户的姓名、客户所在区域名称及其销售代表的姓名和所在部门的名称。

Page 80: 第四章  SQL 和 PL/SQL

1. Select name, dept_id, salary from emp where dept_Id=’31’ or dept_id=’41’ ;

2. Select name, title, manager_id from emp where manager_id is null or manager_id=‘1’ or manager_id=‘2’ order by title, name;

3. Select name, dept_id, salary from emp where salary>2000 and not dept_id =’31’ And not dept_id =’41’;

Page 81: 第四章  SQL 和 PL/SQL

4. Select name,title, dept_id

from emp

where dept_id =’41’

and (title=‘stock clerk’ or title= ‘warehouse manager’);

5. Select C.name “customer”, R.name “region”, E.name “sales rep”, D.name “department”

from customer C, region R, emp Ee, dept D

where C.sales_rep_id=E.id

and C.region_id=R.id

and E.dept_id=D.id

and C.credit_rating=‘poor’;

Page 82: 第四章  SQL 和 PL/SQL

算术运算及内部函数 SQL 支持的算术运算符()、 × 、 / 、+、

-例 1 :写出一个 SQL查询,结果显示所有

warehouse manager 的工资每月增加 250 后的值。

Select name, salary+250

From emp

Where title=‘warehouse manager’;

Page 83: 第四章  SQL 和 PL/SQL

列名 描述 / 数据类型Product_id 产品惟一的标识号,最长为 7 个字符Warehouse_id 存储产品的仓库 id, 最长为 7 个字符Amount_in_stock 库存中每件产品的数量,最长为 9 个数字

Reorder_point 需要再订货的库存产品的最低数量,最长为 9 个数字

Max_in_stock 库存产品的最大值,最长为 9 个数字Out_of_stock_

explanation

产品无货的原因,最长为 255 个字符

Restock_date 产品再存货的日期,日期数据类型

Inventory 表:

Page 84: 第四章  SQL 和 PL/SQL

例 2: warehouse 101 的仓库经理想知道为每项产品订购 100 件后,是否会高于管理所规定的最大值。

select product_id,

max_in_stock - (amount_in_stock+100)

from inventory

where warehouse_id=‘101’

/

Page 85: 第四章  SQL 和 PL/SQL

例 3 : warehouse 201 的仓库经理决定对 20106 产品及 20108 产品各订购 100 件,产品到货后,如果所得到的每个产品新数量的一半被卖掉,还会剩多少件?该经理需要知道,这些存货量是否低于再订购点以及低多少 (即还需要订购产品的数量 ) 。

select product_id, (amount_in_stock+100)/2 , reorder point,

reorder_point-( (amount_in_stock+100)/2 )

from inventory

where warehouse_id=‘201’ and

(product_id=‘20106’ or product_id=‘20108’)

/

Page 86: 第四章  SQL 和 PL/SQL

内部函数数值函数函数名 返回值

ABS(m) m 的绝对值MOD(m,n) m 被 n除后的余数POWER(m,n) m 的 n 次方ROUND(m [,n] )

m 四舍五入至小数点后 n 位的值 (n缺省为 0)

TRUNC(m [,n]) m截断至 n 位小数位的值 (n 缺省为0)

Page 87: 第四章  SQL 和 PL/SQL

例 1 :对每项存货,显示存货量与再订购点之间的差值以及该差值的绝对值。

Select product_id,warehouse_id,

amount_in_stock-reorder_point, ABS(amount_in_stock-reorder_point)

From inventory

/

例 2 :显示每项存货被 9除后的余数。Select product_id,

warehouse_id,MOD(amount_in_stock,9)

From inventory;

Page 88: 第四章  SQL 和 PL/SQL

例 3 :显示每项存货量及存货量的平方。Select amount_in_stock,

POWER(amount_in_stock,2)

From inventory;

例 4 :1) 将每项存货量用 9除,将结果显示为最接近整数的四舍五入值。

select amount_in_stock/9,

ROUND(amount_in_stock/9)

from inventory;

Page 89: 第四章  SQL 和 PL/SQL

2) 将每项存货量用 9除,显示四舍五入到小数点后一位和后两位的结果。

select amount_in_stock/9, ROUND(amount_in_stock/9 , 1) , ROUND(amount_in_stock/9 , 2) from inventory;3 )将每项存货量用 9除,显示结果到最邻近

的十位及百位数。select amount_in_stock/9, ROUND(amount_in_stock/9 ,- 1) , ROUND(amount_in_stock/9 ,- 2) from inventory;

Page 90: 第四章  SQL 和 PL/SQL

例 5 :嵌套函数显示每次存货数被 81除后的余数四舍五入到最邻近的十位数的值。

Select ROUND(MOD(amount_in_stock,81),-1)

From inventory;

Page 91: 第四章  SQL 和 PL/SQL

重要的转换函数

NVL ( m,n ) : 如果 m 值为 null ,返回值为 n ,否则返回m 。To_char(…) :将数值转换成字符串。To_number(…) :将字符串转换成数值。

Page 92: 第四章  SQL 和 PL/SQL

例 1 :假设 emp 表,该表中 title 列可能存在 null 值,我们想在查询结果中中用‘ unknown’替代。

Select NVL(title,’unknown’)

From emp;

例 2 :我们想对以字符串存储的数进行计算。Select to_number(‘123.45’)+to_number(‘234.56’)

From dual;

例 3 :将 emp 表中雇员的工资用‘ $9,999,999.99’格式化。

Select id, to_char(salary, ‘$9,999,999.99’)

From emp;

Page 93: 第四章  SQL 和 PL/SQL

SUM(n) 和 AVG(n)函数SUM(n) 和 AVG(n)函数分别返回列中所有

值的和及平均值,他们都忽略空值,即并不把空值假定为 0 。

例 1 :显示 emp 表中,月工资的总和及平均值。

Select sum(salary) ,avg(salary)

From emp;

五、分组函数

Page 94: 第四章  SQL 和 PL/SQL

MAX(n) 和 MIN(n)函数MAX(n) 和 MIN(n)函数返回指定列中的最大值和最小值。这两个函数适用于所有数据类型。字符将按它的 ASCII 码计算,而且所有的大写字母比所有小写字母小。

例 2 :显示 warehouse manager 的最高工资和最低工资。

Select max(salary),min(salary)

From emp

Where title=‘warehouse manager’;

Page 95: 第四章  SQL 和 PL/SQL

Count()函数Count(*) :统计整个表的行数。Count(all n ) 和 count( n ) 函数 :显示指定列中已知值的个数。Count( distinct n )函数:返回指定列中不同值的个数。

例 3 :统计 emp 中不同的部门数及表的总行数。

Select count( distinct dept_id ), count(*)

From emp;

Page 96: 第四章  SQL 和 PL/SQL

列名 描述 / 数据类型

Ord_id 与项目相关的定单 ID ,最长为 3 个字符

Item_id 分配给每个项目的惟一的标识号,最长为 7个字符

Product_id 与该项目相关的产品 ID ,最长为 7 个字符

Price 该项目的价格,最长 11 位数,包括 2 位小数

Quantity 该项目的数量,最大为 9 位数

Quantity_shipped 已知产品的定单中该项目的发运数,最大为9 位数

Item 表:单一值和分组函数的结合

Page 97: 第四章  SQL 和 PL/SQL

例 1 :显示定单号 100 中所有订货的合计平均值

Select avg(price * quantity )From itemWhere ord_id =‘100’;例 2 :显示定单号 100 中所有订货价格合计的

最大值与最小值。Select max( price * quantity ), min(price* quantity)From itemWhere ord_id=‘100’;

Page 98: 第四章  SQL 和 PL/SQL

显示指定组的信息Select 列名

from 表名 where 条件 group by 列名 1[, 列名 2…]

having 条件 【 order by 条件】;Where 子句限制 select 语句显示的行

数, having 子句限制了显示的组数。Having 子句中可以使用任何分组函数。

Page 99: 第四章  SQL 和 PL/SQL

Group By 子句例 1 :显示 emp 表中每种工作职务人的平均工资值,职务按字母顺序排列。

Select title, count(*), avg(salary)From empGroup by titleOrder by title;

Count(*)函数返回每个类目内的行数。其中空值被考虑在内了。

Page 100: 第四章  SQL 和 PL/SQL

例 2 :显示每个部门员工的最高工资、最低工资,其中该部门中的人数要 1 个以上。按部门排序。

Select dept_id, max(salary), min(salary)

From emp

Group by dept_id

Having count(*)>1

Order by dept_id;

Page 101: 第四章  SQL 和 PL/SQL

练习:

1. 显示部门名称和 id 以及该部门的员工人数,要求部门的人数要大于 1 。按部门员工总数降序排列。

2. 显示地区 id和地区名以及该地区的客户数。

3.按部门分组,显示平均工资大于 1200元的经理姓名。

Page 102: 第四章  SQL 和 PL/SQL

1. Select emp.dept_id “id”,

dept.name “department”,

count(emp.id) “employees”

from emp, dept

where emp.dept_id=dept.id

group by emp.dept_id,dept.name

having count(emp.id)>1

order by count(emp.id) desc;

Page 103: 第四章  SQL 和 PL/SQL

2. Select region.id,region.name,count(customer.id)

from region,customer

where region.id=customer.region_id

group by region.id,region.name;

3.select E.manager_id,M.name,avg(M.salary)

from emp E, emp M

where E.manager_id=M.id

group by E.manager_id,M.name

having avg(M.salary)>1200;

Page 104: 第四章  SQL 和 PL/SQL

嵌套查询和集合查询嵌套查询或子查询:它允许我们根据另一个查询的结果检索数据。

select ……

from ……

where ……

(select……

from ……

where……)

外层查询,后执行这个查询

子查询,先执行这个内层查询

Page 105: 第四章  SQL 和 PL/SQL

单一行的子查询

例 1 :显示所有工资大于平均工资的雇员的姓名,工资。

Select name, salary

From emp

Where salary>(select avg(salary)

from emp);

Page 106: 第四章  SQL 和 PL/SQL

多行子查询:多行比较运算符

运算符 意义

IN 等于子查询返回值中的任一值,则为 true

NOT IN 不等于或不同于子查询返回值中的任一值,则为true

ANY 一个值与子查询返回值中的每一个值比较。只要有一个成立,则为 true 。

ALL 一个值与子查询返回值中的每一个值比较。都成立时,则为 true 。

Page 107: 第四章  SQL 和 PL/SQL

例 1 :在 dept 表中,显示至少有一位雇员的部门的名称。方法一: select d.name

from dept d, emp e

where d.id=e.dept_id

group by d.name

having count(e.id) >=1;

Page 108: 第四章  SQL 和 PL/SQL

方法二: select distinct name

from dept

where id in (select dept_id

from emp);

Page 109: 第四章  SQL 和 PL/SQL

列名 描述 / 数据类型

Id 每个定单的惟一标识号,最长为 3 个字符

Customer_id 客户的惟一标识号,最长为 3 个字符

Date_ordered 定单的订货日期,日期数据类型

Date_shipped 定单的发运日期,日期数据类型

Sales_rep_id 负责定单的销售代表的惟一标识号,最长为3 个字符

Total 定单的总金额,最长 11 位数,包括 2 位小数

Payment_type 支付方式,最长为 6 个字符

Order_filled 定单是否已经填写,最长为 1 个字符

Ord表

Page 110: 第四章  SQL 和 PL/SQL

例 2 :显示所有在 1992 年 8 月 31 日发出定单的顾客。

select name from customer where id in (select customer_id from ord where date_ordered=’31-8 月 -92’);

Page 111: 第四章  SQL 和 PL/SQL

例 3 :显示任职于一个现有部门的雇员的姓名。 select name

from emp

where dept_id = any(select id

from dept);

例 4 :找出工资最低的雇员。 select name

from emp

where salary<=all ( select salary

from emp);

Page 112: 第四章  SQL 和 PL/SQL

多列子查询Select …

from …

where ( 列名 1 ,…列名 n) in

(select 列名 1 ,…列名 n

from …

where…);

那层查询中的多列。跟外层查询的列数相同,并且有相同的对应域。

Page 113: 第四章  SQL 和 PL/SQL

例 1 :根据表 emp显示经理 id 为 10 且工资和职务相同的所有雇员的姓名、部门号、工资和开始工作的日期。

select name, dept_id, salary, start_date

from emp

where (salary, title) in

(select salary, title

from emp

where manager_id=‘10’);

Page 114: 第四章  SQL 和 PL/SQL

使用子查询创建表拷贝表的结构 例 1 :拷贝 emp 表的结构,而不要它的

数据。将新表称为 worker 。 create table worker

as select *

from emp

where 1<>1;

Page 115: 第四章  SQL 和 PL/SQL

拷贝表中的若干列及其数据例 2: 创建一个表,它包含有 VP职务的雇员的

姓名和部门号。新表名为 vice_president 。 create table vice_president as

select name, dept_id

from emp

where title like ‘%VP%’;

Page 116: 第四章  SQL 和 PL/SQL

利用子查询更新表

列名 描述 / 数据类型

Id 每个仓库的惟一标识号,最长为 7 个字符

Region_id 仓库所在的区域 id, 最长为 3 个字符

City 仓库所在的城市,最长为 20 个字符

Phone 仓库的电话号码最长为 20 个字符

Manager_id 仓库经理的 id, 最长为 3 个字符

Warehouse表

Page 117: 第四章  SQL 和 PL/SQL

例 1 :由于上一年出色的完成了任务,因此,对位于上海的仓库的经理的所有下属雇员每人工资长 1000 元。

update emp

set salary =salary+1000

where manager_id =(select manager_id

from warehouse

where city=‘上海’ ) ;

Page 118: 第四章  SQL 和 PL/SQL

例 2 :假设上海的仓库经理辞职了,由 John临时代替。更新 emp 表

update emp

set manager_id=(select id

from emp

where name=‘John’)

where manager_id=(select manager_id

from warehouse

where city=‘上海’ ) ;

Page 119: 第四章  SQL 和 PL/SQL

利用子查询向表内插入数据

例 1 :将所有在 10 号部门工作的雇员插入到前面建立的 worker 表中。

insert into worker

select *

from emp

where dept_id =‘10’;

Page 120: 第四章  SQL 和 PL/SQL

利用子查询从表中删除行

例 1 :假定由于业务不足,位于上海的仓库已经关闭。在 emp 表中删除所有在这个仓库工作的雇员。

delete from emp

where manager_id=(select manager_id

from warehouse

where city=‘上海’ ) ;

Page 121: 第四章  SQL 和 PL/SQL

集合运算符集合运算符 union( 并 ) 、 Intersect (交)和

minus(差 ) 允许将单独的 select 语句的结果组合起来。Union运算符

该运算符允许我们把多个 select 语句的查询结果合并起来。

例 1:显示所有 region_id 为 1 的顾客姓名和在该地区的部门名称。

Page 122: 第四章  SQL 和 PL/SQL

select name

from customer

where region_id=‘1’

union

select name

from dept

where region_id=‘1’;

Page 123: 第四章  SQL 和 PL/SQL

Intersect运算符该运算符允许找出两个表共有的行。

例 2 :显示所有被指派了客户的销售代表的id 。

select sales_rep_id

from customer

intersect

select id

from emp;

Page 124: 第四章  SQL 和 PL/SQL

Minus运算符该运算符允许我们确定存在于一个表中但不存在于另一个表中的行。

例 3 :由于内部培训,有些销售代表还没有被指派客户,显示这些销售代表的名字。

select name from emp where id = ( select id from emp minus select sales_rep_id from customer);

Page 125: 第四章  SQL 和 PL/SQL

练习:1. 显示定单总金额超过所有定单平均值的顾客的姓名和信誉等级。

2. 创建一个表,它包括信誉等级为 poor 的所有客户信息。表名为 low_rating.

Page 126: 第四章  SQL 和 PL/SQL

1 、 select customer.name,

customer.credit_rating

from customer,ord

where ord.total>(select avg(total)

from ord)

and ord.customer_id=customer.id;

2. Create table low_rating

as select *

from customer

where credit_rating=‘poor’; 返回

Page 127: 第四章  SQL 和 PL/SQL

PL/SQL 的块结构 declare 变量、常量、游标、嵌套的 pl/sql 过程以及函数的定义 begin 执行部分 exception 错误或异常处理 end;注:只有 begin 部分是必须的, declare 和 exception 部分为可选的。

ORACLE 的 PL/SQL

Page 128: 第四章  SQL 和 PL/SQL

变量 变量命名规则: 1. 以字母 A—Z 开头。 2. 后可跟字母,数字( 0—9 )或 $,#,_ 。 3. 长度不超过 30 。 4. 变量名不能有空格。5. 可用数据类型 varchar2 、 char 、 number 、 binary_integer

( 带 符 号 的 整 型 变量 ) 、 pls_integer 、 date 、 boolen

Page 129: 第四章  SQL 和 PL/SQL

范例 1 :匿名块 declare hundreds_counter number(1,-2); begin hundreds_counter :=100; loop dbms_output.put_line(hundreds_counter); hundreds_counter:=hundreds_counter+100; end loop; exception when others then dbms_output.put_line(‘that is an high as we can

go.’); end;

Page 130: 第四章  SQL 和 PL/SQL

函数和过程块 function 函数名 [ (参数列表) ]

return 数据类型 is 或 as

变量声明 begin

执行部分 [exception

错误或异常处理 ]

end;

Page 131: 第四章  SQL 和 PL/SQL

范例 3: 过程块 procedure 过程名 [ (参数列表) ] is 或

as

变量声明 begin

执行部分 [exception

错误或异常处理 ]

end;

Page 132: 第四章  SQL 和 PL/SQL

流程控制分支结构:

IF 语句 :

if 条件 then…

else…

end if;

IF…ELSIF 语句 : if 条件 then… elsif 条件 then… elsif 条件 then… else… end if;

Page 133: 第四章  SQL 和 PL/SQL

例 : 使用 if…elsif 语句确定等级 declare

v_score number := 85;

v_lettergrade char(1);

begin

if v_score>=90 then

v_lettergrade :=‘A’;

elsif v_score>=80 then

v_lettergrade :=‘B’;

elsif v_score>=70 then

v_lettergrade :=‘C’;

elsif v_score>=60 then v_lettergrade :=‘D’; else v_lettergrade :=‘E’; end if; dbms_output.put_line( ‘your letter grade is:’ || v_lettergrade)

Page 134: 第四章  SQL 和 PL/SQL

循环结构 for循环: for 循环变量 in [reverse] 低值 ..高值 loop …… end loop;例: begin for v_loopcounter in 1..5 loop dbms_output.put_line(‘loop counter is’ ||

v_loopcounter); end loop; end;

Page 135: 第四章  SQL 和 PL/SQL

While 循环 while 条件 loop …… end loop; 例: declare v_calc number :=0; begin while v_calc <=10 loop v_calc :=v_calc +1; dbms_output.put_line(‘the value of v_calc

is’ || v_calc); end;

Page 136: 第四章  SQL 和 PL/SQL

Exit 和 exit when 语句范例:在 while循环中使用 exit when 语句 declare

v_radius number :=2;

begin

while true loop

dbms_output.put_line(‘the area is’ || mypi * v_radius * v_radius);

exit when v_radius = 10;

v_radius=v_radius+2;

end;

Page 137: 第四章  SQL 和 PL/SQL

Loop循环 loop

……

exit when…

end loop;

Page 138: 第四章  SQL 和 PL/SQL

declare v_radius number :=2; begin loop dbms_output.put_line(‘the area is’ ||

mypi * v_radius * v_radius); v_radius=v_radius+2; exit when v_radius >10; end loop; end;

Page 139: 第四章  SQL 和 PL/SQL

伪列Currval 和 nextval 与序列 sequence 一起使用。序列用来产生惟一的数字。 Currval返回序列的当前值,而 nextval 在序列中增加新值并返回此值。

如: emp_sequence 序列用来为 emp 表的主关键字生成惟一值 :

Create sequence student_sequence

start with 10000

increment by 1;

Page 140: 第四章  SQL 和 PL/SQL

Insert into emp(id,name,title,salary)

Values(emp_sequence.nextval,'Sam', 'President', 4500);

Insert into emp(id,name,title,salary)

Values(emp_sequence.nextval,'Thomas', 'Sales Representative', 1500);

可用下面的 SQL 语句返回序列的当前值。Select emp_sequence.currval

From dual;

Page 141: 第四章  SQL 和 PL/SQL

% type

pl/sql 变量可用于处理存储在数据库中的数据,在这种情况下,变量应该拥有与表列相同的类型。

如: declare

v_empid emp.id%type;

Page 142: 第四章  SQL 和 PL/SQL

% rowtype

Declare

v_deptrecord dept%rowtype;

定义了一个记录,该记录中的字段将与 rooms表中的列相对应。 v_deptrecord 可拥有下面的结构。

( id varchar2(3),

name varchar2(20),

region_Id varchar2(3))

Page 143: 第四章  SQL 和 PL/SQL

游标PL/SQL 有两种类型的游标: 1. 显式游标。——返回多行的查询 2. 隐式游标。——返回单行的查询处理显式游标的步骤: 1. 声明游标 2. 为查询打开游标 3. 取得结果放入 pl/sql 变量中。 4. 关闭游标

Page 144: 第四章  SQL 和 PL/SQL

1.声明游标

DECLARE v_empid emp.id%TYPE; v_name emp.name%TYPE; v_title emp.title%TYPE := ' Sales

Representative ';

CURSOR c_emp IS SELECT id, name FROM emp WHERE title = v_title;

Page 145: 第四章  SQL 和 PL/SQL

2. 为查询打开游标BEGIN OPEN c_emp; 3.取得结果放入 pl/sql 变量中LOOP FETCH c_emp INTO v_empid, v_name; EXIT WHEN c_emp%NOTFOUND; END LOOP; 4. 关闭游标 close c_emp;End;

Page 146: 第四章  SQL 和 PL/SQL

也可以使用参数化游标: declare cursor c_emp(p_title emp.title%TYPE ) is

SELECT id, name FROM emp WHERE title = p_title; v_empid emp.id%TYPE; v_name emp.name%TYPE; begin open c_emp(' Sales Representative ‘); ……

Page 147: 第四章  SQL 和 PL/SQL

游标属性% notfound:游标 fetch 语句没有返回行,则该属性计算为 true

%found:游标 fetch 语句返回行,则该属性计算为 true

%rowcount: 该属性返回游标打开后至现在,由 fetch 语句已获取的行数。% isopen :游标是打开的,该属性为 true.

Page 148: 第四章  SQL 和 PL/SQL

处理隐式游标BEGIN

UPDATE emp

SET salary = 1000

WHERE id = ‘9’;

IF SQL%NOTFOUND THEN

INSERT INTO emp (id, salary)

VALUES (‘9’, 1000);

END IF;

END;

Page 149: 第四章  SQL 和 PL/SQL

使用 SQL%rowcount 可达到同样的目的BEGIN

UPDATE emp

SET salary = 1000

WHERE id = ‘9’;

IF SQL%rowcount=0 THEN

INSERT INTO emp (id, salary)

VALUES (‘9’, 1000);

END IF;

END;

Page 150: 第四章  SQL 和 PL/SQL

游标循环DECLARE

v_empid emp.id%TYPE;

v_name emp.name%TYPE;

CURSOR c_salesrep IS

SELECT id, name

FROM emp

WHERE title = ' Sales Representative ';

Page 151: 第四章  SQL 和 PL/SQL

BEGIN

OPEN c_salesrep;

LOOP

FETCH c_salesrep INTO v_empid, v_name;

EXIT WHEN c_salesrep%NOTFOUND;

insert into sales_rep (id,name,department )

values (v_empid, v_name, ‘sales');

END LOOP;

CLOSE c_salesrep;

END; 返回