30
第二十章 Oracle9i DML DDL 语句的扩展 Copyright © Oracle Corporation, 2001. All rights reserved. Oracle9i DML DDL 语句的扩展 进度表: 时间 主题 40 分钟 讲演 30 分钟 练习 70 分钟 总共 中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-1

Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

  • Upload
    others

  • View
    13

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

Copyright © Oracle Corporation, 2001. All rights reserved.

Oracle9i 对 DML 和 DDL 语句的扩展

进度表: 时间 主题 40 分钟 讲演 30 分钟 练习 70 分钟 总共

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-1

Page 2: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-2 Copyright © Oracle Corporation, 2001. All rights reserved.

目标

完成本课后, 您应当能够执行下列操作:

• 描述多表插入的特性

• 使用下面的多表插入类型

– 无条件 INSERT

– 枢轴式 INSERT

– 条件 ALL INSERT

– 条件 FIRST INSERT

• 创建和使用外部表

• 在创建主键约束时命名索引

课程目标

本课讲解 Oracle9i/10g 扩展的 DDL 和 DML 语句。这些语句的焦点集中在多表 INSERT 语句,多表 INSERT 语句的类型,外部表,并在创建主键约束时提供索引的

名字。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-2

Page 3: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-3 Copyright © Oracle Corporation, 2001. All rights reserved.

INSERT语句回顾

• 用 INSERT语句添加新行到表中

• 用此语法一次只能插入一行

INSERT INTO table [(column [, column...])]VALUES (value [, value...]);

INSERT INTO table [(column [, column...])]VALUES (value [, value...]);

INSERT INTO departments(department_id, department_name, manager_id, location_id)

VALUES (70, 'Public Relations', 100, 1700);1 row created.

INSERT 语句回顾 你可以发布 INSERT 添加新行到表中。 在语法中:

table 表的名字

column 用于组装数据的表中列的名字 value 列的相应值

注:带 VALUES 子句的语句一次只能添加一行到表中。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-3

Page 4: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-4 Copyright © Oracle Corporation, 2001. All rights reserved.

UPDATE语句回顾

• 用 UPDATE语句修改存在的行

• 如果需要,一次可以修改多行

• 如果使用了 WHERE 字句,可以指定一行或多行被修改

UPDATE tableSET column = value [, column = value, ...][WHERE condition];

UPDATE tableSET column = value [, column = value, ...][WHERE condition];

UPDATE employeesSET department_id = 70WHERE employee_id = 142;1 row updated.1 row updated.

UPDATE 语句回顾 你可以用 UPDATE 语句修改存在的行。 在语法中:

table 表的名字 column 用于组装数据的表中列的名字 value 列的相应值或子查询 condition 确定要被更新的行,由列名、表达式、常量、子查询和比较操作

符组成 查询表显示要更新的行,以确认更新操作。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-4

Page 5: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-5 Copyright © Oracle Corporation, 2001. All rights reserved.

多表 INSERT语句概述

• INSERT...SELECT语句能够作为单个的 DML 语句的

一部分用于插入行到多表中

• 多表 INSERT 语句能够被用在数据仓库系统中从一个或

多个操作源转移数据到一组目的表中

• 下面的方法提供重要的性能改进:

– 单个 DML 与多 INSERT...SELECT语句相对

– 单个 DML 与一个用 IF...THEN 语法做多插入的过程相

多表 INSERT 语句概述 在一个多表 INSERT 语句中,你从来自一个子查询赋值的返回行插入计算行到一

个或多个表中。 多表 INSERT 语句在数据仓库应用中可以扮演非常有用的角色。你需要经常装载

数据仓库数据,它可以提供方便的业务分析用途。为了实现这个目的,来自一个或多个

操作系统的数据需要被取出,并且被复制到数据仓库中。从源系统提取数据和装载数据

到 数 据 仓 库 的 过 程 通 常 被 称 为 ETL , 代 表 提 取 (Extraction) 、 转 换 (Transformation) 和装载 (Loading)。

在提取过程中,希望得到的数据必须从许多不同的来源被确定并且被提取,例如数

据库系统和应用程序。在提取之后,数据必须物理地转换为目的系统或一个中间系统以

备进一步处理。根据所选择的转换方法,一些转换可以在处理过程中进行。例如,一个

通过网关直接访问一个远程目标的 SQL 语句可以连接作为 SELECT 语句的一部分的

两个列。 一但数据被装载到 Oracle9i 数据库、数据转换就可以用 SQL 操作来完成。用

Oracle9i 多表 INSERT 语句是实现 SQL 数据转换的方法之一。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-5

Page 6: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

多表 INSERT 语句概述 (续)

当多表作为目的时,多表 INSERTS 语句提供 INSERT ... SELECT 语句的好

处。用 Oracle9i 以前的功能,你不得不处理多个 INSERT ... SELECT 语句,并

因此多次处理相同的源数据,还增加了多次转换工作。 当使用现有的 INSERT ... SELECT 语句时,新的语句可以用直接装载机制被并

行使用以获得更快的性能。 来自输入流的每条记录,例如非关系数据库表,现在可以被转换为多记录以用于许

多关系数据库表环境。在 Oracle9i 之前为了实现这个功能,你必须写多个 INSERT 语句。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-6

Page 7: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-7 Copyright © Oracle Corporation, 2001. All rights reserved.

多表 INSERT语句的类型

Oracle9i 引入下面的多表插入语句的类型:

• 无条件 INSERT

• 条件 ALL INSERT

• 条件 FIRST INSERT

• 枢轴式 (Pivoting) INSERT

多表 INSERT 语句的类型 Oracle 9i 引进了下面的多表 INSERT 语句类型: 无条件 INSERT 条件 ALL INSERT 条件 FIRST INSERT 枢轴式 INSERT 用不同的子句指出被执行的 INSERT 类型。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-7

Page 8: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-8 Copyright © Oracle Corporation, 2001. All rights reserved.

多表 INSERT语句

INSERT [ALL] [conditional_insert_clause][insert_into_clause values_clause] (subquery)

[ALL] [FIRST][WHEN condition THEN] [insert_into_clause values_clause][ELSE] [insert_into_clause values_clause]

conditional_insert_clause

语法

多表 INSERT 语句 幻灯片显示了多表 INSERT 语句的一般格式。有四种多表插入语句类型。 无条件 INSERT 条件 ALL INSERT 条件 FIRST INSERT Pivoting INSERT

无条件 INSERT: ALL insert_into_clause 指定所有跟随着的多表 insert_into_clauses 执行无条件的多表插入。对于

每个由子查询返回的行 Oracle 服务器执行每一个 insert_into_clause 一次。 条件 INSERT: conditional_insert_clause

指定 conditional_insert_clause 来执行一个条件多表插入。Oracle 服务

器通过相应的 WHEN 条件过滤每一个 insert_into_clause,确定是否执行这个 insert_into_clause。一个单个的多表插入语句可以包含 多 127 个 WHEN 子句。 条件 INSERT: ALL

如果你指定 ALL,Oracle 服务器求每一个 WHEN 子句的值,而不管任何其他 WHEN 子句求值的结果。对于每个条件求值为 true的 WHEN 子句,Oracle 服务器

执行相应的 INTO 子句列表。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-8

Page 9: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

多表 INSERT 语句 (续) 条件 FIRST: INSERT

如果指定 FIRST,Oracle 服务器对每一个出现在语句顺序中的 WHEN 子句求值。

如果第一个 WHEN 子句的值为 true,Oracle 服务器对于给定的行执行相应的 INTO 子句,并且跳过后面的 WHEN 子句。 Conditional INSERT: ELSE Clause

对于给定的行,如果无 WHEN 子句的值为 true: 如果指定了 ELSE 子句,Oracle 服务器 执行与 ELSE 子句相关联的 INTO

子句列表。 如果没有指定 ELSE 子句,Oracle 服务器对于哪个行不采取任何行动

在多表 INSERT 语句上的约束 你只能在表而不能在视图上执行多表插入。 你不能执行执行一个多表插入到一个远程表。 在执行一个多表插入时,你不能指定一个表集合表达式。 在一个多表插入中,所有的 insert_into_clauses 不能组合指定多于

999 个目列。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-9

Page 10: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-10 Copyright © Oracle Corporation, 2001. All rights reserved.

INSERT ALLINTO sal_history VALUES(EMPID,HIREDATE,SAL)INTO mgr_history VALUES(EMPID,MGR,SAL)SELECT employee_id EMPID, hire_date HIREDATE,

salary SAL, manager_id MGR FROM employeesWHERE employee_id > 200;

8 rows created.8 rows created.

无条件 INSERT ALL

• 从 EMPLOYEES 中选择 EMPLOYEE_ID大于200的雇员的 EMPLOYEE_ID, HIRE_DATE, SALARY, 和MANAGER_ID值

• 用多表 INSERT插入这些值到 SAL_HISTORY和MGR_HISTORY 表中

无条件 INSERT ALL 幻灯片中的例子插入行到 SAL_HISTORY 和 MGR_HISTORY 表中。SELECT 语

句从 EMPLOYEES 表中取回那些 employee ID 大于 200 的雇员的 employee ID, hire date, salary 和 manager ID的详细信息。 employee ID, hire date 和 salary 信息被插入到 SAL_HISTORY 表中;employee ID, manager ID 和 salary 信息被插入到 MGR_HISTORY 表中。

INSERT 语句被用做无条件 INSERT,由于没有进一步的约束被用于那些由 SELECT 语句返回的行,所有被 SELECT 语句返回的行都被插入到两个表 SAL_HISTORY 和 MGR_HISTORY 中。在 INSERT 语句中 VALUES 子句指定那些必

须被插入到每个表中的来自 SELECT 语句的列值。在两个插入中,由 SELECT 语句结

果行返回的行,既用于 SAL_HISTORY 表,也用于 MGR_HISTORY 表。 反 馈 8 rows created 可 以 被 解 释 为 , 在 基 表 SAL_HISTORY 和

MGR_HISTORY 上总共有 8 行插入被执行。

教师注释

为 了 演 示 幻 灯 片 中 的 代 码 例 子 , 你 首 先 必 须 运 行 脚 本 文 件 lab\cre_sal_history.sql 和 lab\cre_mgr_history.sql , 创 建 SAL_HISTORY 和 MGR_HISTORY 表。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-10

Page 11: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-11 Copyright © Oracle Corporation, 2001. All rights reserved.

条件 INSERT ALL

• 从 EMPLOYEES 表中选择 EMPLOYEE_ID大于200的那些雇员的 EMPLOYEE_ID, HIRE_DATE, SALARY 和MANAGER_ID值

• 如果 SALARY大于 $10,000,用一个条件多表 INSERT语句插入这些值到 SAL_HISTORY表中

• 如果 MANAGER_ID大于 200,用一个多表 INSERT 语句插入这些值到 MGR_HISTORY表中

条件 INSERT ALL 在幻灯片中被列举的对于一个条件 INSERT ALL 语句的问题陈述。相应问题的解

决方案显示在下一页中。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-11

Page 12: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-12 Copyright © Oracle Corporation, 2001. All rights reserved.

条件 INSERT ALL

INSERT ALLWHEN SAL > 10000 THENINTO sal_history VALUES(EMPID,HIREDATE,SAL)

WHEN MGR > 200 THEN INTO mgr_history VALUES(EMPID,MGR,SAL)SELECT employee_id EMPID,hire_date HIREDATE,

salary SAL, manager_id MGR FROM employeesWHERE employee_id > 200;

4 rows created.4 rows created.

条件 INSERT ALL (续) 幻灯片中的例子与前面幻灯片中的例子相似,插入行到 SAL_HISTORY 和

MGR_HISTORY 表中。SELECT 语句从 EMPLOYEES 表中取回那些其 employee ID 大于 200 的雇员的 employee ID, hire date, salary 和 manager ID 字段

的详细信息。 employee ID, hire date 和 salary 的详细信息被插入到 SAL_HISTORY 表中;employee ID, manager ID 和 salary 的详细信息被插入

到 MGR_HISTORY 表中。 该 INSERT 语句是条件 ALL INSERT,因为有进一步的约束被应用到那些被

SELECT 语句返回的行上。从被 SELECT 语句返回的行中,只有那些 SAL 列的值大

于 10000 的行被插入到 SAL_HISTORY 表中;类似的,只有那些 MGR 列的值大于 200 的行被插入到 MGR_HISTORY 表中。

观察本例不象前面的例子,前面的例子有 8 行被插入到表中,而在本例中只有 4行被插入。

反 馈 4 rows created 可 以 被 解 释 为 , 在 基 表 SAL_HISTORY 和 MGR_HISTORY 上总共有 4 行插入被执行。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-12

Page 13: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-13 Copyright © Oracle Corporation, 2001. All rights reserved.

条件 FIRST INSERT

• 从 EMPLOYEES表中选择 DEPARTMENT_ID,SUM(SALARY)和 MAX(HIRE_DATE)

• 如果 SUM(SALARY)大于 $25,000 则用一个条件FIRST多表 INSERT 插入这些值到 SPECIAL_SAL 表

• 如果第一个 WHEN 子句的值为 true,则该行的后面的WHEN 子句被跳过

• 对于那些不满足第一个 WHEN条件的行,用一个条件多表 INSERT 基于 HIRE_DATE列的值插入HIREDATE_HISTORY_00, 或HIREDATE_HISTORY_99, 或 HIREDATE_HISTORY表。

条件 FIRST INSERT 对于条件 FIRST INSERT 语句的问题描述在幻灯片中列出。问题的解决方案显示

在下一页。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-13

Page 14: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-14 Copyright © Oracle Corporation, 2001. All rights reserved.

条件 FIRST INSERT

INSERT FIRSTWHEN SAL > 25000 THENINTO special_sal VALUES(DEPTID, SAL)

WHEN HIREDATE like ('%00%') THENINTO hiredate_history_00 VALUES(DEPTID,HIREDATE)

WHEN HIREDATE like ('%99%') THENINTO hiredate_history_99 VALUES(DEPTID, HIREDATE)

ELSEINTO hiredate_history VALUES(DEPTID, HIREDATE)SELECT department_id DEPTID, SUM(salary) SAL,

MAX(hire_date) HIREDATEFROM employeesGROUP BY department_id;

8 rows created.8 rows created.

条件 FIRST INSERT (续)

幻灯片中的例子使用一个单个的 INSERT 语句插入行到多个表中。SELECT 语句

返回 EMPLOYEES 表中每个部门的 department ID, total salary 和 maximum hire date 的详细信息。

该 INSERT 语句被用做条件 FIRST INSERT,合计薪水大于 $25,000 的部门作为

一个例外被处理。条件 WHEN SAL > 25000 首先被求值,如果一个部门的合计薪水

大于 $25,000,那么记录被插入到 SPECIAL_SAL 表中,而不考虑受雇日期 (hire date),如果第一个 WHEN 子句求值为 true,Oracle 服务器执行相应的 INTO 子句,并且对于该行跳过后面的 WHEN 子句。

对于那些不满足第一个 WHEN 条件 (WHEN SAL > 25000) 的行,其余的条件被

用来作为一个条件 INSERT 语句求值,并且由 SELECT 语句取回的记录根据 HIREDATE 列的值被插入到 HIREDATE_HISTORY_00 或 HIREDATE_HISTORY_99 或 HIREDATE_HISTORY 表中。

反 馈 8 rows created 可 以 被 解 释 为 , 在 基 表 SPECIAL_SAL 、

HIREDATE_HISTORY_00、HIREDATE_HISTORY_99 和 HIREDATE_HISTORY 上总

共有 8 个 INSERT 语句被执行。 教师注释

为了演示幻灯片中的代码例子,你必须首先运行脚本文件 lab\cre_special_sal.sql、lab\cre_hiredate_history_99.sql、lab\cre_hiredate_history_00.sql 和 lab\cre_hiredate_history.sql

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-14

Page 15: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-15 Copyright © Oracle Corporation, 2001. All rights reserved.

枢轴式 (Pivoting) INSERT

• 支持从非关系数据库表中接受一组销售记录,SALES_SOURCE_DATA 的格式如下:

EMPLOYEE_ID, WEEK_ID, SALES_MON, SALES_TUE, SALES_WED, SALES_THUR, SALES_FRI

• 你可能想要以一种典型的相关格式存储这些记录到SALES_INFO表中:

EMPLOYEE_ID, WEEK, SALES

• 使用 pivoting INSERT,从非关系数据库表转换销售记

录集到关系格式

枢轴式 (Pivoting) INSERT 枢轴式 (Pivoting) 是一种运算,在其中你需要构建一个转换,对于一个多关系数

据库环境,来自任何输入流的每条记录,例如,一个非关系数据库表, 必须被转换为

多记录。 为了解决幻灯片中提到的问题,你必须构建一个转换,来自原始非关系数据库表

SALES_SOURCE_DATA 的每条记录被转换为数据仓库的 SALES_INFO 表的 5 条记

录。这种转换通常被称为枢轴 (pivoting)。 对于 Pivoting INSERT 语句的问题陈述在幻灯片中列出。该问题的解决方案显示在

下一页。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-15

Page 16: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-16 Copyright © Oracle Corporation, 2001. All rights reserved.

枢轴式 (Pivoting) INSERT

INSERT ALLINTO sales_info VALUES (employee_id,week_id,sales_MON)INTO sales_info VALUES (employee_id,week_id,sales_TUE)INTO sales_info VALUES (employee_id,week_id,sales_WED)INTO sales_info VALUES (employee_id,week_id,sales_THUR)INTO sales_info VALUES (employee_id,week_id, sales_FRI)SELECT EMPLOYEE_ID, week_id, sales_MON, sales_TUE,

sales_WED, sales_THUR,sales_FRI FROM sales_source_data;

5 rows created.5 rows created.

枢轴式 (Pivoting) INSERT (续) 幻灯片中的例子,从非关系数据库表 SALES_SOURCE_DATA 接收销售数据,这

些数据记录了销售代表在一周中每天的详细资料,每周有一个单独的周 ID。 DESC SALES_SOURCE_DATA

教师注释 为了演示幻灯片中的代码例子,你必须首先运行脚本文件

lab\cre_sales_source_data.sql、lab\cre_sales_info.sql 和 lab\popul_sales_source_data.sql。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-16

Page 17: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

枢轴式 (Pivoting) INSERT (续) SELECT * FROM SALES_SOURCE_DATA;

DESC SALES_INFO

SELECT * FROM sales_info;

观察前面使用 Pivoting INSERT 的例子,来自 SALES_SOURCE_DATA 表的一行

被转换为 5 条相关表 SALES_INFO 的记录。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-17

Page 18: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-18 Copyright © Oracle Corporation, 2001. All rights reserved.

外部表

• 外部表是只读表,在外部表中数据被存储在数据库外面的文件中

• 用 CREATE TABLE 语句创建外部表的元数据

• 借助外部表的帮助,Oracle 数据能够被作为文件存储或卸载

• 数据能够用 SQL 查询,但你不能用 DML 并且不能创建索引

外部表

一个外部表是一个只读表,其元数据被存储在数据库中,但它的数据被存储在数据

库的外部。使用 Oracle9i 外部表特性,你可以用外部数据作为一个虚拟表。该数据可以

被查询和直接连接,并且可以并行,不要求外部数据首先被装载到数据库中。你可以用 SQL、PL/SQL 和 Java 查询外部表中的数据。

在外部表和常规表之间的主要不同是,外部组织的表是只读的。无 DML 操作 (UPDATE、INSERT 或 DELETE) 的可能,并且在它们上面无索引可以被创建。

可以通过 CREATE TABLE ... ORGANIZATION EXTERNAL 语句定义外部表的

元数据。该外部表定义可以被看作一个视图,该视图可用于运行任何 SQL 查询,而不

需要先将外部数据装载到数据库中。 Oracle 服务器提供两种主要的访问驱动程序用于外部表。一种是装载访问驱动程

序,或 ORACLE_LOADER,用于使用 Oracle 装载技术从外部文件读数据,该访问驱

动程序允许 Oracle 服务器从其格式可以被 SQL*Loader 实用程序解释的任何数据

源访问数据。另一种 Oracle 提供的访问驱动程序,导入/导出 (import/export) 访问驱动程序,或 ORACLE_INTERNAL,既可以用于导入数据,也可以用于导出使用

平台无关格式的数据。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-18

Page 19: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-19 Copyright © Oracle Corporation, 2001. All rights reserved.

创建外部表

• 与 CREATE TABLE 语法一起用external_table_clause创建一个外部表

• 指定 ORGANIZATION 作为 EXTERNAL来指出表是位于

数据库之外的

• external_table_clause由访问驱动 TYPE, external_data_properties 和 REJECT LIMIT 组成

• external_data_properties 由下面的部分组成:

– 默认目录

– 访问参数

– 位置

创建一个外部表

用 CREATE TABLE 语句的 ORGANIZATION EXTERNAL 子句创建外部表。你实

际上不是真的创建表,而是在创建你可以用来访问外部数据的数据字典表中的元数据。

ORGANIZATION 子句让你指定表被存储的数据行的顺序。在 ORGANIZATION 子句中

指定 EXTERNAL 子句,指出该表是位于数据库外部的只读表。 TYPE (access_driver_type) 指出外部表的访问驱动程序。访问驱动程序是

应用编程接口 (API),用于为数据库解释外部数据。如果没有指定 TYPE,Oracle 使用默认的访问驱动程序,ORACLE_LOADER。

REJECT LIMIT 子句让你指定在一个 Oracle 错误被返回并且查询失败之前,

一个外部数据的查询期间有多少转换错误可能发生。默认值是 0。 DEFAULT DIRECTORY 让你指定一个或多个对应存放外部数据源的文件系统目录

的默认目录对象。默认目录也可以被用于访问驱动程序存储辅助文件,例如错误日志。

多个默认目录被允许,以方便在多磁盘驱动器上做负载平衡。 可选的 ACCESS PARAMETERS 子句让你为该外部表的特殊访问驱动程序的参数

指定值。Oracle 不解释该子句中的任何事。解释在外部表的上下文中的信息胜于访问

驱动程序。 LOCATION 子句让你为每个外部数据源指定一个外部位置。通常 location_specifier 是

一个文件,但它不是必要的。Oracle 不解释该子句,它被用于访问驱动程序在外部文件的

上下文中解释该信息。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-19

Page 20: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-20 Copyright © Oracle Corporation, 2001. All rights reserved.

创建外部表的例子

创建一个 DIRECTORY 对象,它指出外部数据源所在的

文件系统目录

CREATE DIRECTORY emp_dir AS '/flat_files' ;

创建外部表的例子

用 CREATE DIRECTORY 语句创建目录对象。目录对象为在服务器上存放外部数

据源的文件系统目录指定别名。在引用一个外部数据源时,你可以用目录名字,而不是

硬编码操作系统路径名,这样可以有更大的文件管理灵活性。 你必须有 CREATE ANY DIRECTORY 系统权限来创建目录。当你创建一个目录时,

你自动被授予 READ 对象的权限,并且可以授予 READ 权限给其他用户和角色。DBA 也可以授予该权限给其他用户和角色。 语法

CREATE [OR REPLACE] DIRECTORY AS 'path_name';

在语法中:

OR REPLACE 如果目录数据库对象已经存在,指定 OR REPLACE 来重新它。 你可以用该子句改变一个已经存在的目录的定义,而不需删除它, 再创建,并且重新授予前面已经授予过的与该目录相关的数据库 对象权限。用户在前面已经被授予的权限,在重新定义目录上还 可以访问该目录,而不需要被重新授权。

DIRECTORY 指定要被创建的目录的名字。目录的 大长度是 30 字节。你不 能用方案名限制目录对象。

'path_name' 指定操作系统目录的全路径名,路径名字是大小写敏感的。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-20

Page 21: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-21 Copyright © Oracle Corporation, 2001. All rights reserved.

创建外部表的例子

CREATE TABLE oldemp (empno NUMBER, empname CHAR(20), birthdate DATE)ORGANIZATION EXTERNAL(TYPE ORACLE_LOADERDEFAULT DIRECTORY emp_dirACCESS PARAMETERS(RECORDS DELIMITED BY NEWLINEBADFILE 'bad_emp' LOGFILE 'log_emp' FIELDS TERMINATED BY ',' (empno CHAR,empname CHAR,birthdate CHAR date_format date mask "dd-mon-yyyy"))LOCATION ('emp1.txt'))PARALLEL 5REJECT LIMIT 200;

Table created.Table created.

创建外部表的例子 (续)

假定有一个文件有下面格式的记录:

10,jones,11-Dec-1934 20,smith,12-Jun-1972

记录用新行分界,并且所有域用逗号 ( , ) 结束。文件的名字是: /flat_files/emp1.txt

为了转换该文件为一个外部表的数据源,其元数据将存放在数据库中,你必须完成

下面的步骤:

1. 创建一个目录对象 emp_dir 如下: CREATE DIRECTORY emp_dir AS '/flat_files' ;

2. 运行幻灯片中显示的 CREATE TABLE 命令。 幻灯片中的例子举例说明表的规格,用来创建一个外部表文件:

/flat_files/emp1.txt 在例子中,给出的 TYPE 指定只是为了举例说明它的使用,如果不指定

ORACLE_LOADER 就是默认访问驱动程序。ACCESS PARAMETERS 提供指定访问驱动

程序的参数值,并且由访问驱动程序解释,而不是由 Oracle 服务器解释。 当执行 INSERT INTO TABLE 语句时,PARALLEL 子句使 5个并行执行的服务器

同时扫描外部数据源 (文件)。例如,如果 PARALLEL=5 被指定,那么,多个并行执

行的服务器可以工作在一个数据源上。因为外部表可能非常大,由于性能的原因,指定 PARALLEL 子句或是对于查询的一个并行的线索是明智的。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-21

Page 22: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

创建外部表的例子 (续)

REJECT LIMIT 子句指定,如果在一个外部数据的查询期间发生多于 200个转换

错误,查询就中止并返回一个错误。当访问驱动程序试图转换在数据文件中的数据以匹

配外部表的定义时这些转换错误可能发生。 一旦 CREATE TABLE 命令执行成功,外部表 OLDEMP 就可以象关系表一样被描

述和查询。 DESC oldemp

在下面的例子中,INSERT INTO TABLE 语句从外部数据源产生一个数据流到

Oracle SQL 引擎,数据在那里被处理。由于数据是从外部表中提取得,它被 ORACLE_ LOADER 访问驱动程序透明地从外部表示法转换为相当的 Oracle 本地表示法。

INSERT 语句从外部表 OLDEMP 插入数据到 BIRTHDAYS 表中: INSERT INTO birthdays(empno, empname, birthdate) SELECT empno, empname, birthdate FROM oldemp; 2 rows created.

我们现在可以从 BIRTHDAYS 表中选择。 SELECT * FROM birthdays;

教师注释

为了运行幻灯片中的例子代码,如下操作: 1. 登录到 unix 教师账号并且输入下面的命令:

cd FLAT_FILES pwd

输出应该类似于 /home#/teach#/FLAT_FILES 2. 从 lab 文件夹打开文件 cre_dir.sql,并且用来自 unix pwd 的输出替

换文件中的 后一条命令。 文件中的 后一条命令现在看起来象下面这样:

CREATE OR REPLACE emp_dir as ‘<来自 unix pwd 的输出>'; 3. 保存文件 cre_dir.sql 并且在 iSQL*Plus 执行该文件。 4. 运行 cre_birthdays.sql 脚本来创建 BIRTHDAYS 表。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-22

Page 23: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-23 Copyright © Oracle Corporation, 2001. All rights reserved.

查询外部表

SELECT * FROM oldemp

emp1.txt

查询外部表

外部表不记述存储在数据库中的数据,也不描述数据怎样被存储在外部源中。它描

述外部表层怎样呈现数据给服务器。它是访问驱动程序的职责,并且在外部表层要进行

在数据文件中要求的必要的转换以使它匹配外部表的定义。 当数据库服务器需要访问在外部源中的数据时,它调用适当的访问驱动,以数据库

服务器期望的形式从外部源中获得数据。 在数据源中的数据描述对于区分外部表的定义是重要的。源文件可以比表中的列包

含或多或少的域。同样,在数据源中域的数据类型可能不同于表中列的数据类型。访问

驱动程序确保来自数据源的数据被处理为与外部表的定义相匹配。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-23

Page 24: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-24 Copyright © Oracle Corporation, 2001. All rights reserved.

用 CREATE TABLE语句创建索引

CREATE TABLE NEW_EMP(employee_id NUMBER(6)

PRIMARY KEY USING INDEX(CREATE INDEX emp_id_idx ONNEW_EMP(employee_id)),

first_name VARCHAR2(20),last_name VARCHAR2(25));Table created.Table created.

SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXESWHERE TABLE_NAME = 'NEW_EMP';

用 CREATE TABLE 语句创建索引

在幻灯片的例子中,在 CREATE TABLE 语句中使用 CREATE INDEX 子句显式

地创建主键索引,这是 Oracle9i 提供的增强。你现在可以在主建创建时命名你的索引,

而不象以前,Oracle 服务器在那里创建一个索引,而你却不能对索引的名字有任何控制。

下面的例子举例说明了这一点: CREATE TABLE EMP_UNNAMED_INDEX (employee_id NUMBER(6) PRIMARY KEY , first_name VARCHAR2(20), last_name VARCHAR2(25)); Table created. SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXES WHERE TABLE_NAME = 'EMP_UNNAMED_INDEX';

观察 Oracle 服务器在创建 PRIMARY KEY 列时给索引的名字,该名字含义模糊

又不易理解。用 Oracle9i,你可以在用 CREATE TABLE 语句创建表时命名 PRIMARY KEY 列索引,可是在 Oracle9i 以前,如果你在约束创建时命名主键约束,索引也将用

与约束名相同得名字被创建。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-24

Page 25: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-25 Copyright © Oracle Corporation, 2001. All rights reserved.

小结

在本课中, 您应该已经学会如何:

• 使用 INSERT…SELECT 作为单个的 DML 语句的一部分插入行到多表中

• 创建外部表

• 与 CREATE TABLE 语句一起用 CREATE INDEX 语句命名索引

小结

Oracle 9i 引进了下面的多表插入语句类型。 无条件 INSERT 条件 ALL INSERT 条件 FIRST INSERT 枢轴 INSERT 用 external_table_clause 创建一个外部表。外部表是只读表,其元数据被

存储在数据库中,但它的数据存储在数据库的外面。你不用先把数据装载到数据库中就

可以使用外部表查询数据。 用 Oracle9i,你可以在用 CREATE TABLE 语句创建表时命名主键列索引。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-25

Page 26: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

20-26 Copyright © Oracle Corporation, 2001. All rights reserved.

练习 20 概览

本章练习包括下面的主题:

• 写无条件 INSERT 语句

• 写条件 ALL INSERT 语句

• 重点 INSERT 语句

• 与 CREATE TABLE 命令一起创建索引

练习 20 概览

在该练习中,你将学习写多表插入,并且在表创建的时候连同 CREATE TABLE 命令一起使用 CREATE INDEX 命令。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-26

Page 27: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

练习 20 1. 运行在 lab 文件夹中的 cre_sal_history.sql 脚本创建 SAL_HISTORY 表。

@ \Labs\cre_sal_history.sql

2. 显示 SAL_HISTORY 表的结构。

DESC sal_history

3. 运行在 lab 文件夹中的 cre_mgr_history.sql 脚本创建 MGR_HISTORY 表。

@ \Labs\cre_mgr_history.sql

4. 显示 MGR_HISTORY 表的结构。

DESC mgr_history

5. 运行在 lab 文件夹中的 cre_special_sal.sql 脚本创建 SPECIAL_SAL 表。

@ \Labs\cre_special_sal.sql

6. 显示 SPECIAL_SAL 表的结构。

DESC special_sal

7. a. 写一个查询做下面的操作:

- 从 EMPLOYEES 表中取回那些其雇员 ID 小于 125 的雇员的 employee ID、hire date、salary 和 manager ID 的详细信息。

- 如果薪水高于 $20,000,插入 employee ID 和 salary 的详细信息到 SPECIAL_SAL 表中。

- 插入 employee ID、hire date 和 salary 的详细信息到 SAL_HISTORY 表中。

- 插入 employee ID、manager ID 和 salary 的详细信息到 MGR_HISTORY 表中。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-27

Page 28: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

INSERT ALL WHEN SAL > 20000 THEN INTO special_empsal VALUES (EMPID, SAL) ELSE INTO sal_history VALUES(EMPID,HIREDATE,SAL) INTO mgr_history VALUES(EMPID,MGR,SAL) SELECT employee_id EMPID, hire_date HIREDATE, salary SAL, manager_id MGR FROM employees WHERE employee_id < 125;

b. 从 SPECIAL_SAL 表中显示记录。

SELECT * FROM special_sal;

c. 从 SAL_HISTORY 表中显示记录。

SELECT * FROM sal_history;

d. 从 MGR_HISTORY 表中显示记录。

SELECT * FROM mgr_history;

8. a. 运行在 lab 文件夹中的 cre_sales_source_data.sql 脚本创建

SALES_SOURCE_DATA 表。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-28

Page 29: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

@ \Labs\cre_sales_source_data.sql

b. 运行在 lab 文件夹中的 ins_sales_source_data.sql 脚本插入记录到 SALES_SOURCE_DATA 表中。

@ \Labs\ins_sales_source_data.sql

c. 显示 SALES_SOURCE_DATA 表的结构。

DESC sales_source_data

d. 从 SALES_SOURCE_DATA 表中显示记录。

SELECT * FROM SALES_SOURCE_DATA;

e. 运行在 lab 文件夹中的 cre_sales_info.sql 脚本创建 SALES_INFO 表。

@ \Labs\cre_sales_info.sql

f. 显示 SALES_INFO 表的结构。

DESC sales_info

g. 写一个查询做下面的操作: 从 SALES_SOURCE_DATA 表中取回 employee ID、week ID、周一的销售、周二

的销售、周三的销售、周四的销售、和周五的销售的详细信息。 构建一个转换,这样从 SALES_SOURCE_DATA 表取回每条的记录都被转换为

SALES_INFO 表中的多条记录。 提示:用 pivoting INSERT 语句。

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-29

Page 30: Oracle9i 对DML 和DDL 语句的扩展 - cnblogs.com · 2009-10-22 · 第二十章 Oracle9i对DML和DDL语句的扩展 多表 INSERT 语句 (续) 条件 FIRST: INSERT 如果指定

第二十章 Oracle9i对 DML和 DDL语句的扩展

INSERT ALL INTO sales_info VALUES (employee_id, week_id, sales_MON) INTO sales_info VALUES (employee_id, week_id, sales_TUE) INTO sales_info VALUES (employee_id, week_id, sales_WED) INTO sales_info VALUES (employee_id, week_id, sales_THUR) INTO sales_info VALUES (employee_id, week_id, sales_FRI) SELECT EMPLOYEE_ID, week_id, sales_MON, sales_TUE, sales_WED, sales_THUR,sales_FRI FROM sales_source_data;

h. 从 SALES_INFO 表中显示记录。

SELECT * FROM sales_info;

9. a. 基于下面的实例图表创建 DEPT_NAMED_INDEX 表,命名主键列的索引名字

为 DEPT_PK_IDX。

列名 部门号 部门名字 Primary Key Yes 数据类型 Number VARCHAR2 长度 4 30

CREATE TABLE DEPT_NAMED_INDEX (deptno NUMBER(4) PRIMARY KEY USING INDEX (CREATE INDEX dept_pk_idx ON DEPT_NAMED_INDEX(deptno)), dname VARCHAR2(30));

b. 查询 USER_INDEXES 表,显示适合于 DEPT_NAMED_INDEX 表的 INDEX_NAME。

SELECT INDEX_NAME, TABLE_NAME FROM USER_INDEXES WHERE TABLE_NAME = 'DEPT_NAMED_INDEX';

中国科学院西安网络中心 © 2005 Oracle SQL 入门 20-30