oracle 学习

一、数据库语言部分
1. SQL语言:关系数据库的标准语言
2. PL/SQL:过程化语言Procedural Language
3. SQL*Plus:简单的报表,操作系统接口

4. Oracle 8.01后出现:
(1) 数据分区技术:只适用8.01后的版本,数据分散存放,不要放在一个硬盘上,I/O性能好,安全性能好。
(2) 对象技术:存储过程、函数、包、数据库触发器、动态SQL编程
(3) 数据库权限管理
(4) 数据完整性约束(Data Integrity Constraints)

二、Oracle 数据库核心,数据库管理员DBA
 数据库的管理与日常维护
 数据库总体设计
 数据库存储结构设计:物理结构、逻辑结构
 
/**************************************************************************************************

可以运行Oracle的操作系统:
UNIX:Sun Solaris, HP-UX, AIX, Compaq-Tru64, SCO-UNIX和Linux(运行在PC机上)

Windows NT/2000

P4机器上不能安装Oracle,要想安装需要对安装文件进行修改或者下载补丁程序
在P4机器上安装Oracle的方法(只限于Intel P4机器):
将Oracle的安装光盘拷贝到硬盘上,然后将/stage/components/oracle.swp.jre/win32/bin/symcjit.dll 文件改名为symcjit.org,然后再开始安装。

***************************************************************************************************/

数据库的备份与恢复
优化与性能调整

三、应用系统开发

四、应用服务器OAS

五、在Windows NT/2000下清除Oracle8i运行环境(重新安装前的准备工作):

1. 删除Oracle8i注册表:
regedit.exe => HKLM => Software => ORACLE

2. 删除Oracle8i服务:
regedit.exe => HKLM => System => CurrentControlset => Services => 以Oracle开头的服务

3. 删除Oracle8i事件日志:
regedit.exe => HKLM => System => CurrentControlset => Services => Eventlog => Application => 以Oracle开始的事件

4. 删除Windows NT/2000安装磁盘/Program Files/Oracle目录。

5. 删除Oracle8i环境变量
控制面板 => 系统 => 高级 => 环境变量
(1) 删除CLASSPATH
(2) 编辑PATH,将其中与Oracle有关系的路径删除。

6. 删除Oracle8i菜单

7. 重新启动Windows NT/2000,停止服务。

8. 删除Oracle8i主目录。

/*
IP: 75.64.16.X
Mask: 255.255.248.0
GateWay: 75.64.16.3
DNS: 75.64.16.3
*/

[七、Oracle 网络配置]

/*
(1) 查询数据库名:
SQL> select name from v$database;

(2) 查询数据库实例名:
SQL> select instance_name from v$instance;

(3) 查询数据库服务名:
SQL> select value from v$parameter where name='service_names';  // (小写)

(4)  查询全局数据库名(sys用户):
SQL> select value$ from props$ where name='GLOBAL_DB_NAME';   // 字符串区分大小写
*/

1.  Oracle网络驱动使用SQL*Net v2.0 连接

Oracle for Win98 -> SQL*Net  Easy Configuration

2. Oracle 网络驱动使用Net8 连接

3. Oracle 网络驱动使用Net8i 连接

Oracle程序组-> Network Administration -> Net8 Assistant

[创建TNS连接过程]:
(1) 启动Net8 Assistant
(2) 本地->服务命名
(3) 编辑->创建...
(4) 第一页:网络服务名:给要使用的网络数据库在本机指定一个Host String,自己定义。
(5) 第二页:协议:TCP/IP(Internet协议)
(6) 第三页:
  主机名:输入对方机器的IP地址或域名。
  端口号:默认是1521,一般不需要修改。
(7) 第四页:(Oracle8i)服务名:输入网络数据库的服务名
(8) 第五页:完成。
(9) 菜单:文件->保存网络配置。

监视用户会话:
SQL> select username, sid, serial#, machine from v$session;
删除用户会话:
SQL> alter system kill session 'sid,serail#';

/* 练习
sqlplus stud01/stud01
SQL> show user

SQL> select * from emp;

SQL> select * from dept;

*/
[ // 使用下面的方法可以重复执行上一条SQL语句(在SQL*Plus中)
SQL> l  //小写字母L,显示上一条SQL语句
  1* select username, sid, serial#, machine from v$session
SQL> /  // 正斜杠:重复执行上一条SQL语句

SQL> set linesize 1000  //将SQL*Plus中显示行宽设成1000个字符。

SQL> connect system/manager@orasjz   // 在SQL*Plus中直接连接到另一台机器上的数据库,@字符后是另一台机器的tnsname

]

4. 手工配置Oracle网络连接:主要是配置"tnsnames.ora"文件。
A. 手工配置Oracle网络连接配置文件:tnsnames.ora

(1) 在UNIX中:/u01/app/oracle/product/8.1.6/network/admin/tnsnames.ora

(2) 在Windows 98/NT/2000中:d:/oracle/ora81/network/admin/tnsnames.ora

B. 手工配置Oracle监听进程配置文件:listener.ora

(1) 在UNIX中:/u01/app/oracle/product/8.1.6/network/admin/listener.ora

UNIX下启动进程命令:
$ lsnrctl start    // 启动监听进程
$ lsnrctl status  // 显示监听进程状态
$ lsnrctl stop   // 停止监听进程

(2) 在Windows 98/NT/2000中:d:/oracle/ora81/network/admin/listener.ora

启动进程的命令与UNIX相同。

# LISTENER.ORA Network Configuration File: d:/Oracle/Ora81/network/admin/listener.ora
# Generated by Oracle configuration tools.

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
      )
      (ADDRESS_LIST =
        (ADDRESS = (PROTOCOL = TCP)(HOST = ORA54)(PORT = 1521))
        //注意:上面一行的HOST必须是你的主机名,否则监听会出问题,也可以使用你的机器的IP地址
      )
    )
    (DESCRIPTION =
      (PROTOCOL_STACK =
        (PRESENTATION = GIOP)
        (SESSION = RAW)
      )
      (ADDRESS = (PROTOCOL = TCP)(HOST = ORA54)(PORT = 2481))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = d:/Oracle/Ora81)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = ora54)
      (ORACLE_HOME = d:/Oracle/Ora81)
      (SID_NAME = ora54)   // 注意:ora54为数据库的SID名称,不能更改,否则监听出问题
    )
  )

5. 将主机字符串(Host String)写入注册表(简化SQL*Plus的登录)
regedit.exe -> HKLM -> Software -> Oracle -> home0
增加关键字: local(字符串),键值:主机字符串名。
/* 将下面的内容复制到一个.reg文件中,在Windows 2000中双击执行,即可实现增加或者修改local键值的作用
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOME0]
"local"="ora54"
*/

[SVRMGRL: Server Manager的使用方法]
D:/>svrmgrl

Oracle Server Manager Release 3.1.6.0.0 - Production

版权所有 (c) 1997,1999,Oracle Corporation。保留所有权利。

Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
With the Partitioning option
JServer Release 8.1.6.0.0 - Production

SVRMGR> connect internal  //使用svrmgrl,进入后使用的第一个命令必须是这个命令。
口令:   // 如果要求输入口令,请输入oracle
连接成功。
SVRMGR> select name from v$database;  // 检查当前使用的数据库名
NAME
---------
ORA44
已选择 1 行。
SVRMGR> shutdown immediate  //关闭当前使用的数据库
已关闭数据库。
已卸下数据库。
已关闭 ORACLE 实例。
SVRMGR> startup    //启动当前使用的数据库,如果无效,请使用startup force
已启动 ORACLE 实例。
系统全局区域合计有                         24433932个字节
Fixed Size                                          70924个字节
Variable Size                                     7507968个字节
Database Buffers                                 16777216个字节
Redo Buffers                                        77824个字节
ORA-00205: ?????????????????????
SVRMGR>

[另一个启动oracle数据库的例子]
d:/> sqlplus internal/oracle
SQL> startup force  //强行重新启动数据库。

[修改口令字]
SQL> grant connect to system identified by NewPassword;  //如果用数字作口令,需要使用双引号括起来
SQL> grant connect to sys identified by NewPassword;
SQL> alter user system identified by NewPassword;
SQL> alter user sys identified by NewPassword;
SQL>password  //需要输入原口令

// 注:以上修改口令的方法等价;sys与system用户可以互相修改口令;如果sys与system用户的口令都忘记了,使用如下方法:

D:/>svrmgrl

Oracle Server Manager Release 3.1.6.0.0 - Production

版权所有 (c) 1997,1999,Oracle Corporation。保留所有权利。

Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production
With the Partitioning option
JServer Release 8.1.6.0.0 - Production

SVRMGR> connect internal/oracle
连接成功。
SVRMGR> grant connect to system identified by manager;
语句已处理。
SVRMGR> exit
服务器管理程序结束。

[2002.04.18]
//=========================================================================================================

八、Oracle 产品组成

查询数据库选件产品:
SQL> select * from v$option;
一般都是True, 如果是False, 可以双击激活。
/* cartridges (小产品的)插件,(大产品的)选件(options)*/

[SYS用户是Oracle数据库中权限最大的用户。]

[SQL*Plus登录方法]
1. c:/> sqlplus "/ as sysdba"
2. c:/> sqlplus internal
// 注意:以上两种方法可以类似的使用于SQL*Plus的图形登录界面中
// 用这种登录方法登录进去,所使用的用户均为SYS。
[之所以会出现这种登录方法,是因为在NT的用户组中存在一个ORA_DBA的本地组, 凡在此组中的用户使用操作系统认证,即在此组中的用户登录数据库时不需要密码。]

[orapwd命令:修改internal用户的口令字]
/* orapwd的命令行参数
D:/>orapwd
Usage: orapwd file=<fname> password=<password> entries=<users>

where
    file - name of password file (mand),
    password - password for SYS and INTERNAL (mand),
    entries - maximum number of distinct DBA and OPERs (opt),
  There are no spaces around the equal-to (=) character.  */

修改internal口令字(internal默认口令为oracle)认证方法(A B两个步骤):

A. 修改Oracle登录认证方法:
修改文件SQLNET.ORA文件。
SQLNET.AUTHENTICATION_SERVICES=(NTS) //将这一行前面加上#号注释掉,即可将Oracle的认证方法由操作系统认证改为Oracle认证

SQLNET.ORA文件的位置:
UNIX:/u01/app/oracle/product/8.1.6/network/admin/sqlnet.ora
Windows NT/2000: d:/oracle/ora81/network/admin/sqlnet.ora

B. 修改Internal口令字:
Windows NT/2000:
C:/>ORAPWD file=d:/oracle/ora81/database/pwdora8i.ora
  password=YourPassword  // YourPassword为你要设置的密码
  entries=30
/* ORAPWD file=d:/oracle/ora81/database/pwdora54.ora password=qev entries=30 */

UNIX:
$ orapwd file=$ORACLE_HOME/dbs/orapwSID
  password=YourPassword
  entries=30
然后重新启动Oracle服务(服务->OracleServiceHOSTNAME)。

/* 在执行上述命令之前,需要先将相应目录的pwdora8i.ora(或orapwSID)文件删除或者改名,因为口令字文件不能重名。*/

[tkprof 跟踪文件整理工具]
$ tkprof x.trc x.txt

Windows 2000/NT:
d:/oracle/admin/db_name/udump/*.trc

UNIX:/u01/app/oracle/amdin/db_name/udump/*.trc     // */

九、Oracle数据分区技术:8.0以后开始使用

(一)LOB(Large Object)大对象类型数据:
1. BLOB:存储二进制数据,如图象、视频、声音等,用于代替Long raw类型(Oracle7.0以前的数据类型,今后不再支持)
2. CLOB:存储大字符,如:个人简历,用于代替long字段。
3. NCLOB:其它民族语言的支持
(1) 数据库字符集NLS:
Server端:NLS_CHARACTERSET: (如果为以下的字符集,Oracle的数据库可以用来存储汉字)
 ZHS16GBK(Oraclei8, Oracle8)
 ZHS16CGB231280(Oracle7.3, 8, 8i)

此参数位置在数据字典中,查询核心字符集(语言、日期、货币等):
SQL>select * from nls_database_parameters;

Client端:NLS_LANG=Simplified Chinese_CHINA.ZHS16GBK (如果没有设置,默认是英文)
regedit.exe

UNIX Client中:
$ NLS_LANG="simplified chinese"_china.zhs16gbk
$ export NLS_LANG

//一般将上述环境变量放入.profile文件中。

/***********************************************插入内容********************************************************

(1) sys是一种用户,internal是一种方式,用来启动关闭数据库,9.0以后不再使用internal,全部是sys。

(2) SQL>set com v7  //将8i版本暂时退回到7版

(3) SQL> alter system suspend; // 使用internal用户执行,冻结数据
    SQL> alter system resume;  // 取消冻结,恢复正常

****************************************************************************************************************/

(2)Oracle数据库核心字符集修改方法:

[*] 修改数据字典(使用SYS用户):
SQL>update props$ set value$='ZHS16GBK' where name='NLS_CHARACTERSET';
SQL>commit;
然后重新启动数据库。

4. BFILE:外部文件存储,将数据存储在服务器硬盘

十、Oracle 8i 数据库改变:
1. 网络计算数据库
2. 支持IFS(Internet File System)
3. 集成Java虚拟机

[数据库语言]
第一章  SQL语言基础

一、什么是SQL语言:
Structured Query Language ---- 结构化查询语言

SQL*Plus支持的SQL语言:
1. SQL语言(标准的SQL语言)
2. SQL*Plus语言(非标准):报表或接口
3. PL/SQL 语言(非标准):程序开发(例如存储过程)

二、SQL语言特点:
1. 非过程化语言
2. 功能强
3. 提供视图功能
4. 两种使用方式
(1)交互式
(2)程序式: SQL> @filename.sql

5. 提供数据控制

三、SQL语言分类:
1. 数据查询语言(QL): Query Language
2. 数据操纵语言(DML): 包括数据的插入、更新和删除,Data Manipulation Language
3. 数据定义语言(DDL Data Definition Language): 建表、建视图、建存储过程等
4. 数据控制语言(DCL Data Control Language): 事务控制、包括权限等

四、SQL关键字(命令)
SQL关键字(以下命令为SQL命令,以分号结束)
1. Alter:修改表结构
2. Audit: 审计, NoAudit(取消审计)
3. Commit:数据提交,相反的命令:Rollback(回退)
4. Comment:将oracle的注释写入数据字典
5. Create: 建表、数组、索引、视图等, 相反的命令:Drop
6. delete: 删除表中的数据, Drop是把表中的数据包括结构全部删除
7. Grant:授权, Revoke:收权(权限回收)
8. Insert:在表中插入新行
9. Lock: 将表强行锁住
10. Rename:修改表名
11. Select: 数据查询
12. Update:数据更新,修改某一个列
13. Validate:校验,对数据进行校验。

五、SQL命令的输入:
在SQL>提示符后输入命令,可以输入多行,以分号结束

六、SQL*Plus 关键字:以回车结束
1. @: 执行外部命令,格式:@路径/文件名
2. #: 注释
3. /: 执行上一条命令
4. Accept:接收键盘输入的命令
5. Append(简化为a): 在行尾增加字符串
/* 例
SQL> select * from dep;
select * from dep
              *
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在

SQL> a t
  1* select * from dept
SQL> /

DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 COMPUTER       BEIJING
*/

6. Break: 分组, Syntax: break on 分组列 skip n //n为每两组之间间隔的空行
/* 例:
SQL> break on job
SQL> select * from emp order by job;  // 此处务必按分组列排序

EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
      7788 SCOTT      ANALYST         7566 13-6月 -87       3000                    20
      7902 FORD                       7566 03-12月-81       3000                    20
      7369 SMITH      CLERK           7902 17-12月-80        800                    20
      7876 ADAMS                      7788 13-6月 -87       1100                    20
      7934 MILLER                     7782 23-1月 -82       1300                    10
      7900 JAMES                      7698 03-12月-81        950                    30
      7566 JONES      MANAGER         7839 02-4月 -81       2975                    20
      7782 CLARK                      7839 09-6月 -81       2450                    10
      7698 BLAKE                      7839 01-5月 -81       2850                    30
      7839 KING       PRESIDENT            17-11月-81       5000                    10
      7499 ALLEN      SALESMAN        7698 20-2月 -81       1600        300         30

EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
      7654 MARTIN     SALESMAN        7698 28-9月 -81       1250       1400         30
      7844 TURNER                     7698 08-9月 -81       1500          0         30
      7521 WARD                       7698 22-2月 -81       1250        500         30

已选择14行。

SQL> break on job skip 1
SQL> /

EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------
      7788 SCOTT      ANALYST         7566 13-6月 -87       3000                    20
      7902 FORD                       7566 03-12月-81       3000                    20

7369 SMITH      CLERK           7902 17-12月-80        800                    20
      7876 ADAMS                      7788 13-6月 -87       1100                    20
      7934 MILLER                     7782 23-1月 -82       1300                    10
      7900 JAMES                      7698 03-12月-81        950                    30

7566 JONES      MANAGER         7839 02-4月 -81       2975                    20
      7782 CLARK                      7839 09-6月 -81       2450                    10
      7698 BLAKE                      7839 01-5月 -81       2850                    30

EMPNO ENAME      JOB              MGR HIREDATE          SAL       COMM     DEPTNO
---------- ---------- --------- ---------- ---------- ---------- ---------- ----------

7839 KING       PRESIDENT            17-11月-81       5000                    10

7499 ALLEN      SALESMAN        7698 20-2月 -81       1600        300         30
      7654 MARTIN                     7698 28-9月 -81       1250       1400         30
      7844 TURNER                     7698 08-9月 -81       1500          0         30
      7521 WARD                       7698 22-2月 -81       1250        500         30

已选择14行。
*/
7. Btitle, Ttitle:设置表尾、表头
SQL> Ttitle '表头'
SQL> Btitle '表尾'
SQL> Ttitle off //失效

8. Change: 写错了改正, Syntax: C/old/new
/* 例:
SQL> select * from detp;
select * from detp
              *
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在

SQL> c/tp/pt
  1* select * from dept
SQL> /

DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 COMPUTER       BEIJING
*/

9. Clear: 清除
SQL> clear break   // 清除前面的break设置
SQL> clear buff  // 清除SQL*Plus缓冲区中的SQL语句

10. Column: 列定义,用于定义列的显示格式
语法:SQL> column 列名 format 格式
例:SQL> Column sal format $99.999999

11. computer: 统计计算

12. connect: 从一个用户退出,直接进入另一个用户

13. disconnect: 中断当前用户的连接

14. copy: 远程复制(用的较少,一般数据链路)

15. define:定义

16. undefine:取消定义

17. del: 删除当前行

18. describe(简写desc): 显示表结构
例:SQL> desc emp

19. document: 文档注释

20. edit(简化ed):调入外部编辑器编辑缓冲区中的SQL语句,保存后,可以直接通过“/”运行编辑过的SQL语句

21. get: 将外部文件调入不执行,只供显示
例:SQL> get c:/sqlplus.ora

22. host: 执行操作系统命令
例:SQL> host dir

23. input(简化为I): 行插入,在当前行的后面插入。

24. List(简化为L): 列示

25. Pause: 设置屏幕暂停
SQL> set pause on   //暂停
SQL> set pause off   //不暂停
SQL> set  'more' pause on [???]

26. Quit: 退出

27. Remark: 注释

28. Run(R): 类似“/”

29. Save: 将已经运行过的SQL命令保存到磁盘
例:SQL> save c:/run.sql  replace  //覆盖保存
      append  //追加

30. set: 设置

31. show: 显示环境变量的值

32. Spool: 显示跟踪
例:SQL> spool c:/文件名
SQL> spool off  //停止记录

33. Start: 类似@,执行外部的SQL文件

33. Timing: 服务器端某一命令的执行时间跟踪

七、数据字典:描述系统信息的表、视图、同义词等,由系统自动维护。
例:SQL>select * from tabs;

1. 显示当前所登录的用户:select * from all_users;

2. user_xxx:描述用户创建的对象,如:user_tables,user_views,user_indexes

3. dba_XXX:数据库管理员(sys, system)专用数据字典

4. all_XXX: 描述用户创建的对象,其他用户授权可以存取的对象。
all_objects: 全部的数据字典

[第二章 数据库查询语言(QL)]

一、查询语句基本语法:
1. 查询全表的数据:
SQL> select * from emp;

2. 查询某(几)个列:SQL> select ename, sal from emp;

3. DISTINCT 标识:只显示不相同的列
例:
SQL> select job from emp;  // 显示结果中有相同的记录
SQL> select distinct job from emp; // 只显示不相同的职业

4. 使用order by将显示结果排序:ASC升序(默认),DESC降序

5. 使用where指出查询条件:
SQL> select * from emp where sal > 2000;

[字符型或日期型用单引号括起来,并区分大小写]

6. 设置日期显示格式:
(1) 确定日历格式:设置参数nls_calendar。

SQL>alter session set nls_calendar='Japanese Imperial'; //设置为日本日历
SQL>alter session set nls_calendar='ROC official';  //设置为*日历
SQL>alter session set nls_calendar='Gregorian';   //设置为格林尼治日历,这是我们要设置成的日历。

SQL> select sysdate from dual;  //查询系统时间

(2) 确定日期格式:参数nls_date_format
常用的日期格式:
yyyy.mm.dd 
yyyy-mm-dd
yyyy/mm/dd 
yyyy"年"mm"月"dd"日"   //如果要显示汉字,请用双引号括起来
yyyy"年"mm"月"dd"日"dy  // dy表示星期

命令格式:
SQL>alter session set nls_date_format='格式';
[此命令只修改前端的显示,退出后即失效,要想永久有效,要修改注册表,在注册表中HKLM->Software->Oracle->Home0增加字符串关键字nls_date_format,键值为日期格式,此处的格式不需要用单引号括起来。]

例:SQL>alter session set nls_date_format='yyyy"年"mm"月"dd"日"dy';

7. Oracle登录自动执行文件glogin.sql:每次用户登录时自动执行该文件,可以将一些环境变量(如linesize)的设置命令或者其它命令放入该文件中。

glogin.sql文件路径:

Windows下:d:/oracle/ora81/sqlplus/admin/glogin.sql

UNIX: /u01/app/oracle/product/8.1.6/sqlplus/admin/glogin.sql

二、运算符与谓词
1、算术运算符:+, -, *, /

SQL> select sal, sal*12 from emp;   //计算工资及年薪。
SQL> select sal, sal+comm from emp;   //错误语句,因为comm中存在空值,会使运算结果也会出现空值。
SQL> select sal, sal + NVL(comm,0) from emp; // 正确语句,NVL为空值运算函数,当comm为空值时,该函数返回第二个值0。

2、逻辑运算符:NOT, AND, OR,三个运算符的优先级别依次降低。

3、比较运算符:>,  <,  =,  >=,  <=,  !=

4、谓词:
(1) IN(或NOT IN):等于(不等于)列表中的任意值。

SQL> select * from emp where job in ('MANAGER', 'CLERK')

(2) (NOT) BETWEEN AND : 表示从小到大的一个范围。[必须是从小到大]
SQL> select * from emp where sal not between 2000 and 3000;

(3) LIKE:模式匹配
SQL> select * from emp where ename like 'S%';   //寻找ename为S打头的记录
%: 表示任意字符串
_(下划线): 表示一个任意字符

SQL> select * from emp where ename like '李%';   //可以使用中文
SQL> select * from emp where ename like 'S_I%';   //寻找ename为S打头,第三个字母为I的记录
SQL> select object_name from all_objects where object_name like 'DBA%'; //搜索数据字典中与dba有关系的对象

(4) <IS> (NOT) NULL(空值):

SQL> select * from emp where comm is NULL;  //查询哪些人没有资金。

5. 伪列:

(1) rowid: 唯一行标识,行被删除之后,rowid不变。
(2) rownum: 行号,一行被删除之后,后面的行号会随之改变

SQL> select empno, ename, rowid, rownum from emp;

[查询SQL语句的相关数据字典]

(1)SQL> select sql_text from v$sqlarea;  //查询以前使用过的SQL语句

(2)查询当前连接用户的SQL语句:
SQL> select user_name,sql_text from v$open_cursor; //需要用sys或system用户执行

三、列名别名
SQL> select ename, sal as Salary from emp;
SQL> select ename  职工姓名, sal 工资 from emp;

* # / / select 都不允许做别名,如果一定要用,用双引号括起来。

[第三章 数据操纵语言(DML)]

一、数据插入:

1. 对于表中全部列插入
语法:SQL> insert into 表名 values(值表达式);

例:SQL> Insert into dept values(51, '软件开发部', '北京');

[*] 用desc显示表结构、数据类型、顺序   SQL> desc dept    //注意,不要将linesize设置的太大,否则看不到表结构,设置成100即可。
[*] 所插数据必须与目标列一致。
[*] 字符与日期数据使用单引号

2. 对于表中部分列插入
语法:SQL> insert into 表名(列名1,列名2...)  values(值表达式);
[*]对于表中的非空列必须插入数据

SQL> insert into emp(empno, ename, job, hiredate,deptno) values(1234, '李大力', '工程师', sysdate - 30, 10);

/* sys 或 system 用户访问其它用户的表的方法

SQL> connect system/ab@ora44
已连接。
SQL> select * from user01.emp      */

/******************** commit 及 Rollback用法:下例是Rollback的一个例子。
SQL> delete dept where deptno = 51;

已删除 1 行。

SQL> select * from dept;

DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 COMPUTER       BEIJING

SQL> rollback;

重算已完成。

SQL> select * from dept;

DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 COMPUTER       BEIJING
        51 软件开发部     北京

已选择6行。
*************************************************/

3. 使用参数(变量),临时输入值

SQL> insert into 表名(列名1,列名2, ...) values(&x1, &x2, ...);

SQL> insert dept(deptno, dname, loc) values(&x1, '&x2', '&x3')

/* 例:
SQL> insert into dept values(&x1, &x2, &x3)   //&x2, &x3没有用单引号括起来
输入 x1 的值:  52
输入 x2 的值:  'bb'        // 字符型数据输入时需要输入单引号
输入 x3 的值:  'cc'        // 同上
原值    1: insert into dept values(&x1, &x2, &x3)
新值    1: insert into dept values(52, 'bb', 'cc')

已创建 1 行。

SQL> select * from dept;

DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 COMPUTER       BEIJING
        51 软件开发部     北京
        52 bb             cc

已选择7行。

SQL> insert into dept values(&x1, '&x2', '&x3');  // 在命令行中给字符或日期型参数加上单引号,则下面输入时不再需要输入单引号

输入 x1 的值:  53
输入 x2 的值:  dd
输入 x3 的值:  ee
原值    1: insert into dept values(&x1, '&x2', '&x3')
新值    1: insert into dept values(53, 'dd', 'ee')

已创建 1 行。
********************************************************************/

// define x = 7788      
// 也可以这样用:select &x1, &x2 from emp;

4. 使用子查询从另一个表中复制数据
语法:Insert into 表名 select 子句;

SQL> insert to emp(empno, hiredate, deptno)
  select deptno+7300, sysdate, deptno from dept;

SQL> insert to emp(empno, hiredate, deptno)
  select deptno+7300, sysdate, deptno from dept@数据库链路名;    //表示dept这个表在网络上的其它服务器中,注意:@之后不是连接串。

SQL> create table pay as select ename, sal from emp; // 用复制的方法创建表
SQL> insert into pay select * from pay;    //自己复制自己,可以使一个表飞速扩大。

二、数据更新
语法:SQL> Update 表名 set 列名=值表达式  where 条件;

例:
SQL> update emp set sal = sal + 100 where sal < 2000;
SQL>update emp set sal = 5000, job='MANAGER' where ename = 'SMITH';
SQL> update emp set comm = 100 where comm is null;

三、数据删除
语法: SQL> Delete from 表名 where 条件;       //删除数据保留结构,可以回退
  SQL>Truncate table 表名;    //删除数据保留结构,不可以回退,效率高
  SQL>Drop table 表名;     //删除数据及结构,不可以回退
 
[第四章 数据控制语言(DCL)]

一、事务提交:对于数据的插入、更新、删除,只有提交后,数据才真正改变,在提交之前,只有修改了数据的用户才可以看到数据的改变,而其他用户看不到数据的改变。

1. 显式数据提交语法:SQL> commit;

/* 某一个用户对表进行更新等写操作之后,如果没有commit,那么其它用户不能对表进行更新操作,否则就会死掉。
查锁方法:
SQL> select username, sid, serial# from v$session;

解锁方法:
SQL> alter system kill session 'sid, serial#';

*****************************************************************************************************/

2. 隐式数据提交:
下列命令是隐式提交命令:
Create, Alter, Drop, Connect, Disconnect, Grant, Revoke, Rename, Exit, Quit, Audit, NoAudit

3. 自动数据提交:
SQL> set autocommit on   //打开自动数据提交开关
SQL> set autocommit off   //关闭自动数据提交开关(默认)

二、事务回退
语法:SQL>Rollback;  //使数据库回退到最近一次提交后状态,如果一次也没有提交过,回到最原始状态
SQL>Rollbac;
SQL>Rollba;
SQL>Rollb;
SQL>Roll;
//以上的用法都是正确的。

三、设置保存点:
SQL> SavePoint a;

回退到保存点:
SQL> Rollback to a;   //此处的Rollback不能再简写。

[第五章 数据定义语言(DDL)]

包括:创建基表、视图、同义词、索引、数据库链路、序列等

一、创建基表
语法:
SQL> Create Table 表名(
 列名1 数据类型,
 列名2 数据类型,
 ...);    //最多可以到1000个字段

例:SQL> Create Table product(
  p_name, varchar2(20),
  p_id_number number(7),
  p_date date);

1. 数据类型
(1)字符型
char(n): n<=2000,固定长度,如果实际长度不够,前面用空格补齐。
varchar2(n): n<=4000,可变长度,不用空格补齐。
(2) 数字型 number(n):整数, number(n,d):小数
(3) 日期型
(4) 二进制raw(8i以前的,现在不支持了)
(5) 大字符long:建议不要使用,现在不支持了
(6) blob:存储二进制
(7) CLOB:存储大字符

SQL> Create table employee(
 name varchar2(30),
 salary number(7,2),
 b_date date,
 phote blob,
 resume clob);
 
[*]修改数据库兼容性参数(如果在执行上面的SQL语句时,提示clob字段“默认字符集具有不同的宽度”,则需要修改数据库兼容性。):
D:/oracle/amdin/db_name/pfile/init.ora
compatible=8.0.5 =改为=> 8.1.0或8.1.5
改完后重新启动数据库使修改生效。
/**********************************************
修改前:
SQL> Create table employee(
  2   name varchar2(30),
  3   salary number(7,2),
  4   b_date date,
  5   phote blob,
  6   resume clob);
 resume clob)
 *
ERROR 位于第 6 行:
ORA-22866: 默认字符集具有不同的宽度

修改后:
SQL> Create table employee(
  2   name varchar2(30),
  3   salary number(7,2),
  4   b_date date,
  5   phote blob,
  6   resume clob);

表已创建。

************************************************/

2. 约束条件:数据完整性约束条件(Data Integrity Constaints)

Oracle 常用约束条件:
(1) 非空约束:NOT NULL
(2) 唯一性约束:UNIQUE
(3) 主键:PRIMARY KEY,主键同时具有上面两个约束条件,一个表中只允许有一个主键。
(4) 外键:FOREIGN KEY,这一列值从其它表中取出,允许重复,但不允许修改。
(5) 检查:CHECK  (e.g. check (sal > 200)
(6) 引用(参考):REFERENCES,只能用其它表或者本表的某一列列值,不能随便修改。
(7) 缺省值:DEFAULT,如果没有输入,自动使用DEFAULT值。

3. 约束条件的定义方法:
可以定义为列的一部分,也可以定义为表的一部分。
(1)定义为列的一部分:
SQL> Create Table product(
 p_name varchar2(20) unique,
 p_id number(7) primary key,
 p_date date not null);

[*] Check、Default约束条件:
SQL> Create table employee(
 name varchar2(20),
 id number(7) primary key,
 sal number(11) check(sal > 200 and sal < 2000),
 h_date date default sysdate);

一个列具有多个约束条件的写法:
SQL> Create Table product(
 p_name varchar2(20) unique,
 p_id number(7) primary key,
  check(p_id >= 111 and p_id <= 999),
 p_date date not null);

例:
SQL> insert into employee(name, id, sal) values('Smith', 2, 201);
SQL> select * from employee;

NAME                         ID        SAL H_DATE
-------------------- ---------- ---------- --------------
ChenZheng                     1        500 2002年04月14日
Smith                         2        201 2002年04月19日

(2)定义为表的一部分(不能用在Default 和 Not NUll的定义上):
SQL> Create Table  Product(
 p_name varchar2(20),
 p_id number(7),
 p_date date not null,
 constraint p_id_pk primary key(p_id),
 constraint p_name_uk unique(p_name));
 
[*] 查询约束条件:
SQL> select * from user_constraints where table_name = 'PRODUCT';

(3) 另一种约束定义方法:
SQL> Create Table  Product(
 p_name varchar2(20),
 p_id number(7) constraint pk_p_id primary key,
 p_date date constraint fk_p_date not null);
 
4. 使用外键创建主从基表
(1) 创建主表(定义主表):
SQL> Create Table product(
 p_name varchar2(20),
 p_id number(7) primary key,
 p_date date not null);
 
(2)创建子表,定义外键
SQL> create table sales_list(
 sales_name varchar2(20),
 sales_id number(7) primary key,
 p_id number(7),
 constraint p_id_fk foreign key (p_id) references product(p_id));
 
5. 数据完整性约束条件的修改
(1) 删除约束条件:
A. 删除主键约束:
SQL> Alter table product drop primary key;
SQL> Alter table product drop constraint p_id_pk;

// 以上两种方法等价

B. 删除唯一性约束:
SQL> Alter table product drop unique(p_name);
SQL> Alter table product drop constraint p_id_uk;

C. 删除非空约束
SQL> Alter table product modify(p_date NULL);

D. 删除缺省值:
SQL> Alter table product modify(p_date default null);

(2) 增加约束条件
A. 增加主键约束:
SQL> Alter table product add primary key(p_id);
SQL> Alter table product add constraint p_id_pk primary key (p_id);

B. 增加非空约束
SQL> alter table product modify ( p_date not null);

C. 增加缺省值
SQL> Alter table product modify (p_date default sysdate-1);

[*]查询缺省值:
SQL> select table_name, column_name, data_default from user_tab_columns;

二、修改表结构
1. 在表中增加新列:
SQL> Alter table product add (p_list number(7), p_loc varchar2(20));

2. 删除一个列(只适用于Oracle8i以后的版本):

SQL> Alter table product drop(p_list, p_loc);  //删除多个列
SQL> Alter table product drop column p_list;   //删除一个列

3. 修改列宽:
SQL> Alter table product modify (p_name varchar2(40));
//增加列宽没有约束,但减小列宽要求列中数据为空。使用此命令也可以修改列的数据类型。

三、视图(View):视图是虚表。
[*]视图不存储数据
[*]数据来源于基表
[*]不是数据的复制
[*]在同一个表上可以创建多个视图

1. 创建视图的语法:
SQL> Create or Replace view 视图名
 as select 语句;
 
例:SQL> create view manager
  as
  select * from emp where job='MANAGER';  // select * from tab; 检查
 
 SQL> select * from manager;  // 查询视图如果查询表
 
// 第二次创建视图,可以使用or replace参数,不需要再删除而直接覆盖同名视图。
 SQL> create or replace view manager
    as
    select * from emp where job='MANAGER';
   
[几点说明:]
(1) 在创建视图时,不得使用order by排序。
(2) 在视图中插入数据,则数据被插入到基表中,所以,如果要向视图插入数据,则创建视图时,必须包含表中全部非空列。
(3) 用户视图数据字典:
SQL> select view_name,text from user_views;

2. 视图列别名:

错误语句:
SQL> create view payment as
 select sal, sal*12, nul(comm,0)/sal from emp;  // 错误原因:视图可以视同为表,所以列名也要符合规定,而sal*12则是不符合规矩的列名。

正确语句:
SQL> create view payment(c1, c2, c3) as  // c1, c2, c3即为视图列别名
 select sal, sal*12, nvl(comm,0)/sal from emp;

3. 创建视图时增加约束条件:WITH CHECK OPTION

SQL> Create or replace view deptno20 as
 select empno, ename, deptno from emp where deptno=20;

SQL> Insert into deptno20 values(1236, '李力', 30);

SQL> select * from deptno20;

// 上面的语句会出现能够通过视图入基表中插入数据,但却不能通过视图看到插入的数据的问题,解决办法:
SQL> Create or replace view deptno20 as
 select empno, ename, deptno from emp where deptno=20
 WITH CHECK OPTION;

4. 创建Oracle8i的实体化视图(Materialized View):视图不依赖于基表,基表被删除后,视图仍然正常。一般用于两个远程数据库之间的访问,通过数据链路来实现。

(1) 以DBA用户登录,为用户授予创建实体化视图的权限:
SQL> Grant Create Materialized View to 用户名;

(2)以获权用户登录,创建实体化视图:
SQL> Create Materialized View manager as
 select * from emp where job = 'MANAGER';
 
(3) 删除实体化视图:
SQL> Drop Materialized View manager;

删除基表:
SQL>drop table 表名;

删除视图:
SQL> drop view 视图名;

三、创建数据库链路(Database link):
数据库链路:用于数据库之间的远程数据复制。

DB1(UNIX) <------- DB2(NT)

若要将DB2中的数据复制到DB1,则需要在DB1中创建数据库链路指向DB2数据库。

创建数据库链路的步骤:
(1) 创建好连接串。
(2) 创建数据库链路。

1. 创建数据库链路的语法:
SQL> Create database link 数据库链路名
 connect to 用户名 identified by 口令
 using '主机字符串';

[*]数据库链路名必须与远程数据库的全局数据库名(数据库名.域名,若没有数据库名,就是数据库名)相同
[*]用户名及口令为远程数据库的用户名及口令
[*]主机字符串为本机tnsnames.ora中网络连接串。

SQL> Create database link ora31 connect to user30 identified by user30 using 'ora31';

2. 使用数据库链路:
SQL> select * from product@ora31;
SQL> insert into product@ora31 values(...);
SQL> Create table product as select * from product@ora31;

3. 删除数据库链路:
SQL> Drop database link ora31;

(一) 创建数据库触发器实现两个数据库之间实时数据传输。
DB1(UNIX) <------- DB2(NT)
若要将DB2中的数据复制到DB1,则需要在DB1中创建数据库链路指向DB2数据库。

[*]在对方的数据库(DB2)上建立触发器,即数据发送方的数据库上建立触发器。
[*]在数据发送方建立指向DB1的数据库链路。

[操作步骤(假设db1为ora31, db2为ora8i):]
(1) 在DB1上建立用来复制远程数据的表:
SQL> Create table product
 as select * from product@ora31;

(2) 在DB2上建立到DB1的数据库链路:
SQL> Create database link ora31 connect to user30 identified by user30 using 'ora31';

(3) 在DB2上建立触发器:
SQL> Create or Replace trigger insert_product before insert on product
 for each row
 Begin
  Insert into product@ora8i
  values(:new.p_id, :new.p_name);
 End insert_product;

// 上述创建数据库触发器的语句,请以.号结束,然后以/执行。

/* 查看SQL语句执行的错误信息:
SQL> show errors
*/

(4) 在DB2上测试数据的自动复制是否成功:
SQL> Insert into product values(1005, '测试商品');  // 在db2的表中插入一条数据
SQL> select * from product;       // 检查数据是否正确插入本地表
SQL> select * from product@ora31;      // 检查数据是否复制到了db1的表中

查询数据库链路信息:
SQL> select username, password from user_db_links;

数据更新:
SQL> Create or Replace trigger update_product
 before update on product
 for each row
 Begin
  update product@ora8i
  set p_id = :new.p_id, p_name = new.p_name where p_id = :old.p_id
 End update_product;

数据删除:
SQL> Create or Replace trigger delete_product
 before delete on product
 for each row
 Begin
  delete from product@ora8i where p_id = :old.pid
 End delete_product

(二). 创建快照(实体化视图)实现两个数据库之间定时数据库传输:
快照:要求主副站点数据库的用户名相同

(1) 在主节点创建快照日志
语法:SQL> Create snapshot log on 主节点表名;   //主节点基表必须含有主键

(2) 在副节点创建快照
语法:
SQL> Create snapshot 快照名
 refresh 刷新方式
 next 时间间隔
 with primary key
 for update
 as select * from 主节点表名@数据库链路名;
 
[*]刷新方式:
Compelete:完全刷新
Force:强制刷新(建议使用,强制刷新自动先fast刷新,然后再force刷新)
Fast:快速刷新
[*] 时间间隔:以天为单位。
sysdate + 1/4  // 六个小时刷新一次
sysdate + 1/1440 // 一分钟刷新一次

/******************************* 教师的部分操作语句 *****************************************************

以下SQL语句为在副节点上的操作语句,主节点对应的用户为user30,例中的photo为要创建快照的表名
create user user30 identified by user30;

grant connect, resource to user30;

grant create snapshot to user30;

connect user30/user30

create database link ora31 connect to user30 identified user30 using 'ora31';

select * from photo@ora31;

create snapshot photo
 refresh force
 next sysdate + 1/1440
 with primary key
 for update
 as select * from photo@ora31;

********************************************************************************************************/
 
/************************** 我的操作步骤 ******************************
[1] 主节点:ora8i
SQL> show user
USER 为"STUD29"
SQL> create snapshot log on dept;

实体化视图日志已创建。

SQL> show user
USER 为"STUD29"
SQL> select * from dept;

DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 COMPUTER       BEIJING

SQL> insert into dept values(60, 'test snap', 'snapshot');

已创建 1 行。

提交完成。

[2]副节点

SQL> connect system/ab
已连接。
SQL> create user stud29 identified by stud29;

用户已创建

SQL> grant connect, resource to stud29;

授权成功。

SQL> grant create snapshot to stud29;

授权成功。

SQL> connect stud29/stud29;
已连接。
SQL> connect system/ab
已连接。
SQL> grant create database link to stud29;

授权成功。

SQL> connect stud29/stud29
已连接。
SQL> create database link ora8i connect to stud29 identified by stud29 using 'tea';

数据库链接已创建。

SQL> create snapshot dept
  2  refresh force
  3  next sysdate+1/2880
  4  with primary key
  5  for update
  6  as select * from dept@ora8i;

实体化视图已创建。
*******************************************************************************************/

[Oracle8i 图形界面管理工具]

Oracle 程序组->Enterprise Manager->

(1)先运行该组中的Configuration Assistant,创建一个新的档案资料库(其作用请查询相应界面上的帮助信息)。

(2) 然后运行该组中的Console程序:
登录用户:sysman 密码:oem_temp

然后搜索要管理的节点(使用主机名或者IP地址都可以),节点要想被搜索到,需要先在节点上启动OracleOraHome81Agent服务,要想在节点上使用图形管理工具,要求先启动OracleOraHome81ManagementServer服务。

四、创建索引(indexes):

语法:SQL> create index 索引名 on 表名(列名);

例:SQL> create index index_dept_dname on dept(dname);

索引数据字典:
SQL>select index_name, table_owner, table_name, from user_indexes;

五、创建序列(Sequences):

语法:SQL> Create sequence 序列名
  start with 起始编码
  increment by 步长
  maxvalue 终止编码;

SQL> create sequence id_code
 start with 2
 increment by 2
 maxvalue 999;
 
序列使用方法:
id_code.nextval  // 下一个值
id_code.currval  // 当前值

第一次要使用nextval,然后以后每次使用currval。

insert into student values(id_code.nextval, '姓名');

[*] ||(双竖线)在oracle中是连接符号,将两个字符串连成一个,如:'A' || 'B' = 'AB'

[第六章 数据库分区技术]

一、什么是数据分区?
  数据分区是指把一个表划分成若干小块。在创建表的结构时应考虑好分区方案,选择表中某一列或多列数据作为分区关键字,该关键字决定哪些数据分到哪些区。Oracle对分区进行管理,新插入数据自动存储到相应的分区。

二、创建分区表:

SQL> Create table employee (
 id number(7),
 name varchar2(20),
 sal number(7,2))
 Partition by range(sal)
 (Partition p1 values less than(500) tablespace users,
 Partition p2 values less than(800) tablespace tools,
 partition p3 values less than(1000) tablespace system);

// p1, p2, p3是三个分区的名字,users, tools, system是三个表空间的名字。less than是小于(不包含)。
几点说明:
[.] 所插数据不得大于LESS THAN中的最大值
[.] 可以使用MAXVALUE(如上面的语句中,要求工资不能大于1000,如果出现这种情况,则应该改成下面的语句:
SQL> Create table employee (
 id number(7),
 name varchar2(20),
 sal number(7,2))
 Partition by range(sal)
 (Partition p1 values less than(500) tablespace users,
 Partition p2 values less than(800) tablespace tools,
 partition p3 values less than(1000) tablespace system,
 partition p4 values less then(maxvale) tablespace users);
 
[.] 不指定表空间时,则该区使用该用户的缺省表空间。
* 查询每个用户的用户缺省表空间:
SQL> select username, default_tablespace from dba_users; // 使用dba用户查询

[*]查询可以使用的表空间名字:
SQL> select tablespace_name, file_name from dba_data_files; // 使用dba(sys或system)来执行

SQL> select dba_users.username, dba_users.default_tablespace, dba_data_files.file_name
 from dba_users, dba_data_files
  where dba_users.default_tablespace = dba_data_files.tablespace_name;

[temp表空间不能用于数据分区。]

三、分区表的查询方法:
SQL> select * from employee;   // 按没有分区的方法查询

SQL> select * from employee partition(p1);   // 只查询p1分区的数据。
SQL> create table part3 as select * from employee partition(p3);

四、分区表的修改:
1、增加分区:
SQL> Alter table employee ADD
 partition p4 values less than(1500) tablespace users;

[*]分区数据字典:
SQL> select partition_name, high_value, tablespace_name
 from user_tab_partitions
 where table_name = 'EMPLOYEE';
 
2、删除分区:
SQL> Alter table employee DROP partition p4;   // 结构数据全部删除(相应分区及数据全部被删除)
SQL> Alter table employee TRUNCATE partition p4;  // 保留结构(即区还存在),数据删除

3、修改区名:
SQL> Alter table employee RENAME partition p4 to p5;

4、分区数据移动:将分区数据从一个表空间移动到另一个表空间
SQL>Alter table employee MOVE partition p4 tablespace system;

5、分区的拆分:

SQL> Alter table employee SPLIT
 partition p3 at(900)
 into(partition p31, partition p32);
 
/* 关于数据字典的几点说明:
v$打头的数据字典,后面不会以s结尾,例如:V$database, v$session;
user打头的,后面都会以s结尾(复数), 如:user_tab_partitions, user_tables
dba打头的,有的以s结尾,有的不。
***************************************************************************/

6、分区的合并:
SQL> Alter table employee MERGE partitions p31, p32 into partition p3;

[第七章 SQL*Plus 报表功能]

/**********************  插入内容:数据字典的一些说明 *****************************
(1) user_XXX:用户,例如:user_tables
(2) dba_XXX: DBA专用
(3) all_XXX: 本用户建的,或者其它用户创建本用户可以查询的(需要其它用户的授权)
(4) v$XXX: 动态数据字典,如:v$database, v$instance, v$session,这些数据字典在oracle不启动时也能查询
***********************************************************************************/
一、定义表头与表尾
SQL> ttitle '表头'

SQL> btitile '表尾'

失效:SQL> ttitle off
 SQL> btittle off

二、定义列名
语法:SQL> column 列名 heading 别名   // 别名不区分大小写

三、定义列格式:
SQL> column 列名 Format 格式
常用列格式:An :  A为字符,n为最大字符宽度。

$99.9999.99
9.99eeee

例:SQL> Column sal format $99.9999.99
SQL> Column comm like Sal

四、分组命令:
语法:SQL> break on 列名 skip n
例:SQL> break on deptno skip 2
SQL> select * from emp order by deptno;

五、统计计算:
语法:SQL> compute 函数 of 统计列 on skip n  //可以使用的函数有:sum, max, min, avg,count, var(斜方差), std(标准差)
例:SQL> compute sum of sal on deptno
清除命令:SQL> clear compute
  SQL> clear break
  SQL> clear column

增加报表级统计:
SQL> break on deptno on REPORT
SQL> compute sum of sal on report
// 整个报表出一个结果,上面两行都要运行,那么整个报表会根据你的设置出一个sum of sal的总计结果。

[第八章 函数]

一、日期格式转换函数:to_char(日期变量,'格式')  // 格式要用单引号括起来

(1) 日期格式构成方法:

年   月   日   时    分  秒
  yy    mm   dd   hh(12小时制)  mi  ss
  yyyy   mon   dy(星期)  hh24(24小时制)
     month  day  
 
A. yy.mm.dd, yy/mm/dd, yy-mm-dd, yyyy.mm.dd, ... 加中文也可以,中文要用又引号括起来

SQL>select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') from dual;  // dual是一个虚拟表,任何用户都可以使用。

二、聚组函数:从一组中返回汇总信息
聚组函数有:Sum, count, count distinct, max, min, avg, stddev(标准差)

例:SQL>select min(sal), max(sal), avg(sal), sum(sal) form emp;
SQL> select ename, job, sal from emp where sal=(slect max(sal) from emp);
SQL> select count(*) from emp;
.....[请参考PowerPiont教程:SQL讲稿.ppt]

[第九章 复杂查询]

一、连接查询:
问:Smith在哪里工作?
答:SQL> select loc from dept, emp where ename = 'SMITH' and emp.deptno = dept.deptno;

二、集合查询[请参考PowerPiont教程:SQL讲稿.ppt P29,30,31]
集合操作是将多个基表的查询结果作UNION运算。
交操作: Intersect
差操作:MINUS

三、子查询(Subqueries):
子查询是在where子句中包含的查询语句,是由系列简单构成的复杂查询。

问:谁与smith在同一部门工作?
答:SQL> select deptno from emp where ename = 'SMITH';
SQL> select ename from emp where deptno = 20;

将两个语句合起来:Select ename from emp where deptno = ( select deptno from emp where ename = 'SMITH');

[第十章 Oracle 权限设置]

一、权限分类:
系统权限:系统规定用户使用数据库的权限。(系统权限是对用户而言)。

实体权限:某种权限用户对其它用户的表或视图的存取权限。(是针对表或视图而言的)。

二、系统权限管理:
1、系统权限分类:
DBA: 拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构。

RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构。

CONNECT:拥有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构。

对于普通用户:授予connect, resource权限。
对于DBA管理用户:授予connect,resource, dba权限。

2、系统权限授权命令:
[系统权限只能由DBA用户授出:sys, system(最开始只能是这两个用户)]
授权命令:SQL> grant connect, resource, dba to 用户名1 [,用户名2]...;

[普通用户通过授权可以具有与system相同的用户权限,但永远不能达到与sys用户相同的权限,system用户的权限也可以被回收。]

例:
SQL> connect system/manager
SQL> Create user user50 identified by user50;
SQL> grant connect, resource to user50;

查询用户拥有哪里权限:
SQL> select * from dba_role_privs;
SQL> select * from dba_sys_privs;
SQL> select * from role_sys_privs;

删除用户:SQL> drop user 用户名 cascade;  //加上cascade则将用户连同其创建的东西全部删除

3、系统权限传递:
增加WITH ADMIN OPTION选项,则得到的权限可以传递。

SQL> grant connect, resorce to user50 with admin option;  //可以传递所获权限。

4、系统权限回收:系统权限只能由DBA用户回收
命令:SQL> Revoke connect, resource from user50;

系统权限无级联,即A授予B权限,B授予C权限,如果A收回B的权限,C的权限不受影响;系统权限可以跨用户回收,即A可以直接收回C用户的权限。

三、实体权限管理
1、实体权限分类:select, update, insert, alter, index, delete, all  //all包括所有权限
execute  //执行存储过程权限

user01:
SQL> grant select, update, insert on product to user02;
SQL> grant all on product to user02;

user02:
SQL> select * from user01.product;

// 此时user02查user_tables,不包括user01.product这个表,但如果查all_tables则可以查到,因为他可以访问。

3. 将表的操作权限授予全体用户:
SQL> grant all on product to public;  // public表示是所有的用户,这里的all权限不包括drop。

[实体权限数据字典]:
SQL> select owner, table_name from all_tables; // 用户可以查询的表
SQL> select table_name from user_tables;  // 用户创建的表
SQL> select grantor, table_schema, table_name, privilege from all_tab_privs; // 获权可以存取的表(被授权的)
SQL> select grantee, owner, table_name, privilege from user_tab_privs;   // 授出权限的表(授出的权限)

4. DBA用户可以操作全体用户的任意基表(无需授权,包括删除):
DBA用户:
SQL> Create table stud02.product(
 id number(10),
 name varchar2(20));
SQL> drop table stud02.emp;

SQL> create table stud02.employee
 as
 select * from scott.emp;
 
5. 实体权限传递(with grant option):
user01:

SQL> grant select, update on product to user02 with grant option; // user02得到权限,并可以传递。

6. 实体权限回收:
user01:
SQL>Revoke select, update on product from user02;  //传递的权限将全部丢失。

四、同义词(Synonym):

1、创建私有同义词:
语法:SQL> create synonym 同义词名 for 代替项;

user01:
SQL> grant select, upate on product to user02;

user02:
SQL> Create synonym product for user01.product;

SQL> select * from product;  // 这里的product即user01.product。

同义词数据字典:
SQL> select synonym_name, owner, table_name from all_synonyms;
SQL> select synonym_name, table_name from user_synonyms;

2、DBA可以创建公共同义词(Public Synonym):公共同义词全体用户可以存取
语法:SQL> create public synonym 公共同义词名 for 代替项;

SCOTT:
SQL> grant select on payment to public;

SYSTEM:
SQL> create public synonym payment for scott.payment;

3. 删除同义词:
User:SQL> drop synonym 私有同义词名;

DBA: SQL> drop public synonym 公共同义词名;

[PL/SQL程序设计]

一、PL/SQL概述
PL/SQL块结构:
Declare
 -- 变量定义部分
Begin
 -- 可执行语句
Exception
  -- 例外处理:对于程序运行中的错误信息、警告信息的说明
End;
.  // 以.号结束程序编写

二、PL/SQL语言的特点(参考PowerPoint教程)
1. PL/SQL中可以定义变量,变量有其作用范围。
2. PL/SQL是以块的方式设计,块中可以嵌套子块,子块可以位于块中任何部分。
3.

x. PL/SQL是以块为单位,SQL语句以语句为单位。

7. 减少对Oracle核心的访问,降低网络负载。

三、PL/SQL与SQL语言(参考PowerPoint教程)
1. PL/SQL语句不能使用DDL语句。
可以使用的SQL语句:Insert, Update, Delete, [select into], commit, rollback, savepoint

...

四、PL/SQL基础
1. 变量的使用
2. 单行注释:--
  多行注释:/*   */

3. 数据类型:
(1)布尔型: Boolean(TRUE, FALSE, NULL)
(2)数字型:NUMBER
INT = INTEGER

(3) 字符型,基本上没有变化
(4) 日期型
(5) 二进制数据:raw, blob

4. 数据定义:
 变量名 数据类型
 变量名 数据类型:=初始值

5. 变量赋值:变量 := 值;

[*]%TYPE:数据类型匹配

s1 char(20);
s2 s1%TYPE; // 定义s2变量,其类型与s1完全匹配。

v_sal emp.sal%type;  // v_sal变量的类型与emp表中的sal字段的数据类型完全匹配,%TYPE最经常使用的方法

[*] %ROWTYPE: 行类型,用于存储数据库基表的一条记录。
定义方法:变量 基表名%rowtype;

例:
SQL> set serveroutput on  // 使能屏幕打印函数的输出

Declare // 如果PL/SQL程序中没有定义变量,那么Declare可以省略
 v_empno emp.empno%type := &empno;
 r emp%rowtype;
Begin
 select * into r from emp where empno = v_empno;
 dbms_output.put_line('姓名'|| r.ename||'工资'||r.sal||'日期'||r.hiredate); 
 // r.字段名:表示某一列的值;dbms_output.putline()是一个屏幕打印函数
End;

[*] 记录类型Record:
 record:
Declare
 v_empno emp.empno%type := &empno;
 // 定义record类型
 type r_emp is record(
  v1 emp.ename%type,
  v2 emp.job%type,
  v3 emp.hiredate%type);
 
 r r_emp;   -- 定义变量r为record类型r_emp
Begin
 select ename, job, hiredate into r from emp where empno = v_empno;
 dbms_output.put_line('姓名:'|| r.v1||'职务:'||r.v2||'工作时间:'||r.v3);
End;

[*] Table类型:类似于C语言中的结构类型数组:
定义方法:TYPE [table_emp] is Table of [emp.ename%type] index by binary_integer;  // []内为用户可以修改的部分

使用:mytable = table_emp;
 mytable(0) := 'SCOTT';
 ...
例:
Declare
 v_empno emp.empno%type := &empno;
 type t_emp is table of emp.ename%type index by binary_integer;
 
 t t_emp;
Begin
 select ename into t(10) from emp where empno = v_empno;
 dbms_output.put_line('编码为'||v_empno||'的员工是'||t(10));
End;

五、条件控制语句:条件判断语句
1. IF-THEN语句:
IF 条件成立 THEN
 可执行语句; 
END IF;

Declare
       v_empno emp.empno%type :=&empno;
       v_ename emp.ename%type;
       v_sal emp.sal%type;
    Begin
      select sal,ename into v_sal,v_ename from emp
      where empno=v_empno;
      if v_sal<2000 then Begin
                  update emp set sal=sal+100
                  where empno=v_empno;
       dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
      End if;
    End;

2. IF-THEN-ELSE语句

IF 条件成立 THEN 
 执行语句1;
ELSE
 执行语句2;
END IF;

Declare
       v_empno emp.empno%type :=&empno;
       v_ename emp.ename%type;
       v_sal emp.sal%type;
Begin
      select sal,ename into v_sal,v_ename from emp
      where empno=v_empno;
      if v_sal<2000 then Begin
                  update emp set sal=sal+100
                  where empno=v_empno;
       dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
      Else dbms_output.put_line('员工'||v_ename||'的工资已经超过规定值,不予更新!');
      End if;
End;
 
3. IF-THEN-ELSIF语句
     IF       条件1成立  THEN  执行语句1;
     ELSIF 条件2成立  THEN   执行语句2;
     ELSIF 条件3成立  THEN   执行语句3;
     ...
     END  IF;
    
Declare
       v_empno emp.empno%type :=&empno;
       v_ename emp.ename%type;
       v_sal emp.sal%type;
    Begin
      select sal,ename into v_sal,v_ename from emp
      where empno=v_empno;
       if v_sal<2000 then Begin
                  update emp set sal=sal+100
                  where empno=v_empno;
        dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
        elsif v_sal<2500 then Begin
                  update emp set sal=sal+50
                  where empno=v_empno;
        dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
        elsif v_sal<3000 then Begin
                  update emp set sal=sal+10
                  where empno=v_empno;
        dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
        else dbms_output.put_line('员工'||v_ename||'的工资已经超过规定值,不予更新!');
        End if;
    End;
 
六、循环语句:
1. 基本循环:
LOOP
       执行语句;
EXIT WHEN 条件成立;
END LOOP;

例:
Declare
         v_deptno emp.deptno%type:=&deptno;
         i number(2):=0;
     Begin
         loop
           i := i +1;
           insert into emp(empno,hiredate,deptno)
           values(i+7200,sysdate,v_deptno);
           dbms_output.put_line('i的当前值为:'||i);
          exit when i=10;
          end loop;
    End;

2. WHILE循环:

WHILE 条件成立
LOOP 执行语句;
END LOOP;

Declare
         v_deptno emp.deptno%type:=&deptno;
         i number(2):=0;
     Begin
         while i  < 10   loop
           i := i +1;
           insert into emp(empno,hiredate,deptno)
           values(i+7200,sysdate,v_deptno);
           dbms_output.put_line('i的当前值为:'||i);
       --   exit when i=10;
          end loop;
    End;
   
3. FOR循环:
FOR 计数器 IN 低界..高界
LOOP 执行语句;
END LOOP;

例:
Declare
         v_deptno emp.deptno%type:=&deptno;
         i number(2):=0;
     Begin
         while i  < 10   loop
           i := i +1;
           insert into emp(empno,hiredate,deptno)
           values(i+7200,sysdate,v_deptno);
           dbms_output.put_line('i的当前值为:'||i);
       --   exit when i=10;
          end loop;
    End;

七、光标设计(Cursor):

1、什么是光标?在PL/SQL中,当查询语句执行结果超过一行时,为处理每一行,必须定义一个cursor,叫光标。

2、光标使用方法:
(1) 定义光标:
语法:光标名 is select 语句;

(2) 打开光标:
语法:open 光标名;

(3) 取数据:
语法:Fetch 光标名 into 变量;

(4) 光标下移:使用loop循环

(5) 关闭光标:close 光标名;

例:
Declare
        v1 emp.empno%type;
        v2 emp.ename%type;
        v3 emp.sal%type;
        cursor c is select empno,ename,sal from emp;
     Begin
         open c;
         loop
         fetch  c into v1,v2,v3;
         if v3<3000 then Begin
                           update emp set sal=sal+100
                           where empno=v1;
                    dbms_output.put_line('员工'||v2||'工资已经更新!');
                                    End;
         end if;
         exit when c%NOTFOUND;
         end loop;
         close c;
     End;
/

-- //要求从emp表中取出按用户输入要求的前几位工资最高的人员及其工资放入topsalary表中:
-- // 我的方法:
SQL>create table topsalary (
 name varchar2(20),
 sal number(7,2));
 
SQL>Declare
  vcount number(7) := &n;
  i number(7) :=0;
        vname emp.ename%type;
        vsal emp.sal%type;
        cursor c is select ename,sal from emp order by nvl(sal,0) desc; --// 使用nvl函数防止工资出现空值的情况,老师补充
     Begin
      delete topsalary;  -- // 先清空topsalary表
         open c;
        
         for i in 1 .. vcount loop
         fetch  c into vname, vsal;
        
         insert into topsalary values(vname,vsal);
        
         end loop;
         close c;
     End;
 
--//教师的方法
Declare
    i number(3) :=&i;
    j number(3) :=0;
   cursor c is select ename,sal from emp order by nvl(sal,0) desc;
   v1 emp.ename%type;
   v2 emp.sal%type;
Begin
   open c;
   loop
   j := j+1;
   fetch c into v1,v2;
   insert into topsalary  values(v1,v2);
   exit when j=i;
   end loop;
   close c;
End;

3. 光标属性:  每一个光标有四种属性
%FOUND         查询语句(FETCH语句)返回记录
%NOTFOUND      查询语句(FETCH语句)无返回记录,用于循环退出条件
%ROWCOUNT     FETCH已获取的记录数
%ISOPEN        光标已打开标记

例:
Declare
        v1 emp.empno%type;
        v2 emp.ename%type;
        v3 emp.sal%type;
        cursor c is select empno,ename,sal from emp;
     Begin
         open c;
         loop
         fetch  c into v1,v2,v3;
         if v3<3000 then Begin
                           update emp set sal=sal+100
                           where empno=v1;
                    dbms_output.put_line('员工'||v2||'工资已经更新!');
                                    End;
         end if;
         exit when c%NOTFOUND;
         end loop;
         dbms_output.put_line('光标处理的行数:'||C%ROWCOUNT);
         close c;
     End;
    
4. 隐式光标处理: 隐式光标是指在处理SQL时,不需定义光标,所使用的SQL语句包括:INSERT ,UPDATE,DELETE子句。

隐式光标属性:       SQL%FOUND        SQL%NOTFOUND              SQL%ROWCOUNT

隐式光标的使用:
Declare
 v_empno emp.empno%type:=&empno;
Begin
 delete from emp where empno=v_empno;
 if SQL%NOTFOUND then
  dbms_output.put_line('你的删除失败,数据库无此人:'||v_empno);
 end if;
End;

[例外处理Exception]
Declare
       v_empno emp.empno%type :=&empno;
       v_ename emp.ename%type;
       v_sal emp.sal%type;
Begin
      select sal,ename into v_sal,v_ename from emp
      where empno=v_empno;
       if v_sal<2000 then Begin
                  update emp set sal=sal+100
                  where empno=v_empno;
        dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
        elsif v_sal<2500 then Begin
                  update emp set sal=sal+50
                  where empno=v_empno;
        dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
        elsif v_sal<3000 then Begin
                  update emp set sal=sal+10
                  where empno=v_empno;
        dbms_output.put_line('员工'||v_ename||'工资已经修改!');
                                       End;
        else dbms_output.put_line('员工'||v_ename||'的工资已经超过规定值,不予更新!');
        End if;
Exception   -- // 例外处理
 when NO_DATA_FOUND then dbms_output.put_line('数据库中没有编码为'||v_empno||'的员工。');
 when TOO_MANY_ROWS then
  dbms_output.put_line('你的查询语句返回结果出现多行,请定义光标后重试!');
 when OTHERS then
  dbms_output.put_line('你的程序是错误的,请仔细检查后重试!');
End;

[用户定义的例外]
(1)在Declare段定义
(2)在Begin段中用Raise引起。
(3)在Exception段中使用。

Declare
       v_empno emp.empno%type :=&empno;
       no_result exception;
Begin
 delete from emp where empno = v_empno;
 if SQL%NOTFOUND then raise no_result;
 end if;
 
Exception   -- // 例外处理
 when NO_DATA_FOUND then dbms_output.put_line('数据库中没有编码为'||v_empno||'的员工。');
 when NO_RESULT then dbms_output.put_line('数据库中没有编码为'||v_empno||'的员工。');
 when TOO_MANY_ROWS then
  dbms_output.put_line('你的查询语句返回结果出现多行,请定义光标后重试!');
 when OTHERS then
  dbms_output.put_line('你的程序是错误的,请仔细检查后重试!');
End;

[存储过程(Storage Procedure)与函数(Function)设计]

一、什么是存储过程?
 存储过程(函数)是把一个PL/SQL块存储到数据库中,作为一个数据库实体,可以在其它存储过程、函数、应用程序中调用。
1、存储过程的调用方法:
(1) 在SQL*Plus中调用方法:SQL> Execute 存储过程名称; // execute 可以简写为Exec。
(2) 在其它存储过程、函数、应用程序中调用方法:存储过程名称;

2、存储过程的设计方法:
编写程序->在SQL*PLUS中编译->修改错误->调用执行。

二、创建存储过程的语法:[参考PowerPoint教程:存储过程1.ppt(P3)]
说明:
 IN: 调用者向过程传递参数
 OUT: 过程向调用者传递参数
 IN OUT: 双向传递参数
 无Declare

[例1:]IN: 删除数据
Create or Replace procedure DelEmp(v_empno in emp.empno%type) is
Begin
 delete from emp where empno=v_empno;
 dbms_output.put_line('编码为'||v_empno||'的员工已被除名!');
End DelEmp;

调用方法:
SQL> Exec DelEmp(7788);
SQL> Exec DelEmp(7934);

[例2:]IN: 插入数据
Create or Replace procedure InsertEmp( v_empno in emp.empno%type,
        v_ename in emp.ename%type,
        v_deptno in emp.deptno%type) is
Begin
 insert into emp(empno, ename, hiredate,deptno)
  values(v_empno, v_ename, sysdate, v_deptno);
 dbms_output.put_line('新员工“'||v_ename||'”录入成功!');
End InsertEmp;

[例3:]IN、OUT:数据查询
Create or Replace procedure QueryEmp(v_empno in emp.empno%type,
                                     v_ename out emp.ename%type,
                                     v_job out emp.job%type) is
Begin
  select ename,job into v_ename,v_job from emp
  where empno=v_empno;
End QueryEmp;

调用方法:
Declare
  v1 emp.ename%type;
  v2 emp.job%type;
   v  emp.empno%type:=&empno;
Begin
    QueryEmp(v,v1,v2);
   dbms_output.put_line('编码为'||v||'的员工姓名是:'||v1||'职业是:'||v2);
End;

[* 查询存储过程源代码:]
SQL> select text from user_source where name = 'DELEMP';  // 名字要大写

三、创建函数语法:
例1:
Create or replace Function GetSalary( v empno%type) return numbwr is
 v_sal emp.sal%type;
Begin
 select sal into v_sal from emp
 where empno=v;
 return v_sal;
End GetSalary;
 
 [调用方法:]
 (1) SQL> Exec dbms_output.put_line(GetSalary(7788));
 (2) SQL> select GetSalary(7788) from dual;
 (3) 使用PL/SQL的方法:
 Begin
  dbms_output.put_line(GetSalary(7788));
 End;

[函数例2]
Create or replace function getmaxsal
return number
is
 v_maxsal emp.sal%type;
 begin
   select max(sal) into v_maxsal from emp;
   return v_maxsal;
 end getmaxsal;
 
  [调用方法:]
 (1) SQL> Exec dbms_output.put_line(GetMaxSal);
 (2) SQL> select GetMaxSal from dual;
 (3) 使用PL/SQL的方法:
 Begin
  dbms_output.put_line(GetMaxSal);
 End;
 
[练习题]: 求n!函数(n的阶乘)。

[我的答案]
Create or replace function nj(n in number)
 return number
 is
   numtmp number;
 Begin
   if n = 0 then
    numtmp := 1;
   else
    numtmp := n * nj(n - 1);
   end if;
  
   return numtmp;
 End nj;
 
 [教师的答案]// 高, 实在是高!!!
Create or replace function fn(n in number)
return number
is
 Begin
  if n=0 then return 1;
 else return n*fn(n-1);
 end if;
End fn;

四、存储过程及函数管理:
1、查询存储过程及函数的源代码:
SQL> select * from user_source;
SQL> select * from dba_source;
SQL> select * form all_source;

2、存储过程及函数的权限管理:
授权命令:
SQL> grant execute on 过程(或函数) to 用户名;
SQL> grant execute on 过程(或函数) to public;  --//授权给全体用户

权限回收:
SQL> Revoke execute on 过程(或函数) from 用户名;
SQL> Revoke execute on 过程(或函数) from public;

3、查询错误信息:
SQL> select * from user_errors;
SQL> show errors;

4、查询依赖性信息:
依赖性:实体的结构定义修改时,对创建在这些实体上的存储过程及函数的影响叫依赖性。

显示依赖性关系:
SQL> select name,type, referenced_owner, referenced_name, referenced_type from user_dependencies;

5、删除存储过程及函数:
SQL> drop procedure 过程名;
SQL> drop function 函数名;

[包(Package)的设计与开发]

一、什么是包?
    把一些相关的存储过程、函数、变量、光标、例外等组合在一起形成的对象叫包。包由包的说明部分及包体两部分组成。定义在包说明部分的是公共元素,定义在包体的部分是私有元素。

二、使用包的优点:     
   1、规范化程序设计
   2、方便过程及函数的组织
   3、便于管理:包的授权只需一次完成
   4、优化系统性能:整个包作为一个整体一次调入内存。

三、包的开发步骤:
1、创建包的说明部分:Create package
2、创建包体部分:Create package body
3、在SQL*Plus中运行创建包
4、在存储过程、其它应用中调用。
在SQL*Plus中调用方法:SQL> exec 包名.过程名;

在存储过程、函数、其它应用中调用方法:包名.过程名;

四、创建包的语法:
1、创建包(说明部分):请参考PowerPoint教程:存储过程1.ppt[Page10]

2、创建包体(Create Package Body): 请参考PowerPoint教程:存储过程1.ppt[Page11]

3、例:请参考PowerPoint教程:存储过程1.ppt[Page12、13、14、15]

五、包的删除:
SQL> drop package 包名;
SQL> drop package body 包名;

查询包源代码:
SQL> select text from user_source where name = '包名';  // 包名大写。

[数据库触发器(Triggers)设计与开发]

一、 什么是触发器?
数据库触发器是一个存储的PL/SQL程序块,它与一个基表联系,当在表上执行特定的数据库维护(插入、删除、更新这三种操作)时,隐含地执行一个PL/SQL程序块。

二、触发器的作用:
 。防止非法的数据库操纵、维护数据库安全
 。对数据库的操作进行审计,存储历史数据
 。完成数据库初始化处理
 。控制数据库的数据完整性
 。进行相关数据的修改
 。完成数据复制
 。自动完成数据库统计计算
 。限制数据库操作的时间、权限等,控制实体的安全性
 
三、触发器的组成:
1、触发时间:触发器事件的时间次序(before, afer)[2]

2、触发事件:什么SQL语句会引起触发器触发(Insert, delete, update)[3]

3、触发子体:触发器触发时要执行的操作(一个完整的PL/SQL程序)

4、触发类型:触发器被执行的次数(语句级、行级)[2] //语句级只执行一次,行级会执行多次。

[*]一个表上最多可以创建12个不同类型的触发器:3*2*2 = 12

四、创建触发器注意事项:
1、在触发器中可以调用存储过程、包;在存储过程中不得调用触发器。

2、在触发器中不得使用commit, rollback, savepoint语句。

3、在触发器中不得间接调用含有commit, rollback, savepoint的语句的存储过程及函数。

五、创建语句级触发器:
语句级触发器: 请参考PowerPoint教程:存储过程1.ppt[Page19] 该触发器在数据库操作时只执行一次。
说明:
 。update中的of是可选项,用于指定语句要修改的列
 。要创建的触发器已经存在时,使用replace选项

//例1:before型触发器:
Create or replace trigger DelEmp
  before delete on emp
  Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18)
   then dbms_output.put_line('现在是非工作时间,请退出!!!');
   end if;
  End;

[触发器数据字典]
SQL> select table_owner, table_name,trigger_body from user_triggers where trigger_name='DELEMP';

//例2:After型触发器:
Create or replace trigger InsertEmp
after insert on emp     // 如果是before,就会比after的结果少一名。
Declare
 v_empcount number(7);
Begin
 select count(*) into v_empcount from emp;
 dbms_output.put_line('目前员工总数已达到:'|| v_empcount|| '名。');
End;

//例3:多个触发条件
Create or replace trigger ChangeEmp
before delete or insert or update on emp
Begin
   if (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between 8 and 18)
   then dbms_output.put_line('现在是非工作时间,请不要修改数据!!!');
   end if;
End;

// 更完善的写法:
Create or replace trigger ChangeEmp
  before delete or insert or update  on emp
  Begin
   if (DELETING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('现在是非工作时间,不要删除数据!');

elsif (UPDATING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8 and 18))
   then dbms_output.put_line('现在是非工作时间,不要更新数据!');

elsif (INSERTING and (To_Char(sysdate,'dy') in ('星期六','星期日') or
        To_number(To_Char(sysdate,'hh24'))  not between  8   and 18))
   then dbms_output.put_line('现在是非工作时间,不要插入数据!');

end if;
  End;

六、创建行级触发器:
等级触发器:增加选项for each row, 使触发器在每一行上触发。

1、创建行级触发器注意事项:
(1) 在行级触发器中,在列名前增加old表示该列修改前值,增加new表示该列修改后值。
(2) 在PL/SQL中引用时,前边增加冒号。
 
[例4: 行级触发器] //必须是对所有的行进行操作才行。
Create or Replace trigger UpdateEmp
Before update on emp
for each row
Begin
 dbms_output.put_line(:old.sal||'--------->'||:new.sal);
End;

[例5:保存历史数据,这种使用方法很重要,用来保存关键表的历史数据]
CReate or Replace trigger ChangeEmp
Before update or delete on emp
for each row
Begin
 Insert into oldemp(empno, ename,job,hiredate,sal)
 values(:old.empno,:old.ename,:old.job,sysdate,:old.sal);
End;

SQL> create table oldemp
 as select empno, ename,job,hiredate,sal from emp where 1>2;

[例6:修改外键]
Create or Replace trigger UpdateDept
after update on dept
for each row
Begin
 update emp
  set emp.deptno = :new.deptno
  where emp.deptno = :old.deptno;
End;

[例7:删除外键、删除相关数据]
Create or Replace trigger DeleteDept
before delete on dept
for each row
Begin
 delete from emp where deptno = :old.empno;
End;

七、触发器管理
1、使触发器失效:
SQL> alter trigger 触发器名称 disable;  // 失效
SQL> Alter Trigger 触发器名称 enable;  // 生效

SQL> Alter table 表名 DISABLE all triggers; // 一个表上的所有触发器失效
SQL> Alter table 表名 ENABLE all triggers; // 使一个表上的所有触发器生效

SQL> Drop Trigger 触发器名;  // 删除触发器;

[第一章] Oracle 数据库体系结构
物理结构
逻辑结构
内存结构
进程结构

[数据库管理员DBA(Database Administrator)]
DBA职责:
。Oracle核心软件安装与产品升级
。为数据库系统分配存储空间及规划未来存储需求
。创建数据库存储结构
。用户权限与角色管理
。监视与控制用户对数据库的存储
。维护数据库安全
。完成数据库备份与恢复
。监视与优化数据库性能

一、物理结构:数据库是由构成数据库的操作系统文件所组成。
UNIX:/u01/app/oracle/oradata/db_name/ *.*
Windows NT/2000: D:/Oracle/oradata/db_name/*.*

//为保证数据安全,只要将此目录中的所有文件备份即可。 Control0X.CTL文件(X为1,2,3)是一样的,只要有一个完好就可以。

包含三类物理文件:
1、数据文件(DataFiles):存储数据库数据的文件,表、索引、存储过程等都存储在数据文件中。

[*]查询数据文件信息:
SQL> select * from dba_data_files;

/* 数据文件的大小只是表示有多少存储数据的空间,并不表示数据量的大小。*/

[*]查询表空间空闲空间:
SQL> select * from dba_free_space;  // 显示结果中包括碎片
SQL>select tablespace_name, sum(bytes) from dba_free_space
 group by tablespace_name;
 
[*] 表空间碎片合并命令:
SQL> alter tablespace 表空间名 coalesce;

SQL> alter tablespace temp coalesce;

[*]数据块大小控制参数:db_block_size = 2K - 32K
在数据库安装后,数据块大小不得修改。

系统缺省值如下:
Oracle7, Oracle8, Oracle8i 8.1.5: 2048(2K)

Oracle8i 8.1.6: 8192(8K)

Oracle8i 8.1.7: 8192(8K)

这个参数存储在d:/oracel/admin/db_name/pfile/init.ora文件中。

SQL> select bytes, blocks, blocks*8192, file_name from dba_data_files;

数据文件的大小都是数据块的整数倍。数据块的大小在数据库安装之前确实,数据库安装之后就不能再修改。

[*] 显示数据块大小:
(1) d:/svrmgrl
SVRMGR> connect internal/oracle

SVRMGR> show parameter db_black_size

SQL> select value form v$parameter where name='db_block_size'; (小写)

[1.1] 在Oracle数据库中,数据文件大小可以修改,命令如下:
SQL> Alter database datafile '数据文件名及路径' resize xxM;

SQL> alter database datafile 'd:/oracle/oradata/ora8i/system01.dbf' resize 100m;
// 上一行中ora8i在具体系统中应该是相应的数据库名

更改之前,查询相应磁盘是否有空闲空间。
用相同的方法可以压缩数据文件的大小,但不能小于已经存储的数据的大小。

[1.2] 在Oracle8i数据库中,数据文件的大小可以自动扩展,命令如下:
SQL> Alter database datafile '数据文件名及路径' autoextend on;  --//该数据文件允许自动扩展(缺省)

SQL> Alter database datafile '数据文件名及路径' autoextend off; --//该数据文件不允许自动扩展

[*] 查询数据文件自动扩展属性:
SQL> select bytes, autoextensible, maxbytes, file_name from dba_data_files;

SQL> Alter database datafile '数据文件名及路径' autoextend on
 next 50m  -- // 每次扩展50M
 maxsize 1000m ; --// 最大扩展到1000M,如果unlimited,则受磁盘大小的限制
 
[*] 查询每次扩展量:
SQL> select bytes, increment_by, file_name from dba_data_files;

[安全起见,建议把自动扩展关闭]

[C.1] Sun Enterprise 6500: 8 * 34G
system01.dbf ==> 33G

SQL> Alter table emp deallocate unused;  --// 压缩表未用空间

2、日志文件(Redo log files):记录数据库修改前后的信息,用于数据库恢复。

每一个数据库至少有两个日志文件组,每组有一个或多个日志成员文件。每个组的成员文件的缺省大小是1M。

[*]假设有三个组,每个组有三个成员文件,Oracle的日志工作流程(概括起来为循环覆盖):

(1) 每个组中的日志成员文件之间的关系是镜像关系,每个成员分别存储到不同的物理磁盘上,只有全部损坏,这个组才算损坏。如果只有一个成员,则这个数据库是不安全的。

(2)

在同一个时刻,只有一个组在工作。当第一组不能全部存放要记录的数据时,则转换到第二组,如果第二组仍然写不下,则转到第三组,第三组仍然存不下,则再转
回到第一组。如果第一组日志的归档模式为归档日志,则第一组日志中存储的数据归档到磁盘或者磁带上,然后数据被覆盖,如果是非归档日志(默认模式,建议改
变为归档模式),则新的数据直接覆盖第一组的数据,这种情况就会造成数据丢失。

[*] 确认数据库(日志)归档方式:
SQL> select log_mode from v$database;

SVRMGR> archive log list

[C*] Oracle的数据库恢复
不完全数据库恢复:通过备份来回退,会造成部分数据的丢失
完全数据库恢复:数据不会丢失。
两种情况下都需要用到日志,日志对于数据库的恢复至关重要。

[*]
(1) 在线日志:v$log  // 当前使用的日志,current
SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------
         1          1        199    1048576          1 NO  CURRENT                 153302 2002年04月
         2          1        197    1048576          1 NO  INACTIVE                112335 2002年04月
         3          1        198    1048576          1 NO  INACTIVE                132450 2002年04月
        
[如果当前日志文件损坏,则数据库无法恢复。(打死也恢复不了)。]
[C*]日志文件组的名称是:REDO0X.LOG(X=1,2,3)。
[对于Oracle数据库来说,还有一个关键文件是SYSTEM01.DBF,如果这个文件坏了,整个数据库系统无法启动,数据也会全部丢失。]

[!!! 一定要做好数据库及日志的备份!!!]

日志文件:v$logfile  // 日志文件
归档日志:v$archived_log  // 日志组切换时归档到磁盘或者磁带上的日志

(4) 历史日志:v$log_history  // 日志的历史记录
SQL> select * from v$log_history;

[*] Redo Log 文件镜像
(1) 一组中Redo Log文件具有相同的信息。
(2) 选择合适的日志文件大小(不能太小,太小容易导致频繁的切换,从而导致过多的磁盘I/O,降低系统的性能)。
[C*] 内存的多少对数据库系统性能的影响是最重要的,日志虽然对系统性能有影响,但没有内存关键,内存一定要大。

[C*] Oracle数据库最大化参数:
maxlogmembers: 最大值是5,缺省值是2。
maxlogfiles:最大254,缺省32个。 // 最大的日志文件个数
maxdatafiles:最大65534, 缺省254。
maxloghistory:最大65534,缺省65534
maxinstances: 最大63,缺省1。

[组不需要太多,至少三个,四个一般就可以了]

[C* 不同日志文件组的文件大小可以不同,两个组中文件的个数也可以不同]
(3) 组中的成员同时被更新。
... [请参考PowerPoint教程]

[*] 日志切换:
DBA强制日志切换命令:SQL> alter system switch logfile;

[*] 在Oracle中,文件的扩展名没有任何意义,从以下数据字典中查询相应的文件的文件名
(1) 表空间文件*.dbf: dba_data_file, v$datafile
(2) 日志文件*.log: v$logfile
(3) 控制文件*.ctl: v$controlfile

SQL> select * from v$log;

查询数据文件同步号:SQL> seelct file#, checkpoint_change#, from v$datafile;

控制文件同步号:SQL> select checkpoint_change# from v$database;

/*

随着日志的切换或者时间的推移,文件的同步号不断改变,如果上述同步号不一致,表明数据库出现问题;由此,不能将不同机器上的单个数据库文件互相拷贝,因
为同步号不一致,只能把一台机器上的所有数据文件同时拷贝到另一台机器上才可以使用。Oracle的同步号以控制文件(*.ctl)中的为准。 */

Oracle不提供修改同步号的命令。如果在一个数据库中出现同步号不一致的情况,说明这个数据库的数据已经有不一致的部分,原因可能是进行了不完全恢复,只有当数据完全恢复后,同步号才能重新变得一致。

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------
         1          1        199    1048576          1 NO  CURRENT                 153302 2002年04月
         2          1        197    1048576          1 NO  INACTIVE                112335 2002年04月
         3          1        198    1048576          1 NO  INACTIVE                132450 2002年04月
上述显示结果中的SEQUENCE#的最大值是65534,如果达到最大值,会自动清零,从头开始。

[*]日志管理与配置命令
A. 增加日志文件组:
SQL> Alter database ADD
 logfile group n('第一个日志成员文件','第二个日志成员文件') size xxM;
// n为组号。第二个日志成员文件为可选的,两个成员文件最好放到不同的物理磁盘上。

SQL>Alter database ADD
 logfile group 4('d:/oracle/oradata/ora8i/log41.log', 'd:/oracle/oradata/ora8i/log42.log')
 size 5m;

SQL>Alter database ADD
 logfile group 4('d:/oracle/oradata/ora8i/log41.log', 'd:/oracle/oradata/ora8i/log42.log')
 REUSE; // 如果在相应的路径下存在同名文件,请加Reuse直接覆盖原来的文件。

[C*]: Oracle不提供修改原来的日志组的属性(文件大小)的命令,解决办法是先创建新的,然后删除旧的

// ************************************* 实际操作内容 ************************************************
SQL> Alter database ADD
  2   logfile group 4('d:/oracle/oradata/ora54/ReDo41.log', 'd:/oracle/oradata/ora54/ReDo42.log')
  3   size 5m;

数据库已更改。

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------
         1          1        199    1048576          1 NO  CURRENT                 153302 2002年04月
         2          1        197    1048576          1 NO  INACTIVE                112335 2002年04月
         3          1        198    1048576          1 NO  INACTIVE                132450 2002年04月
         4          1          0    5242880          2 YES UNUSED                       0

SQL> alter system switch logfile;

系统已更改。

SQL> /

系统已更改。

SQL> /

系统已更改。

SQL> select * from v$log;

GROUP#    THREAD#  SEQUENCE#      BYTES    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ----------
         1          1        199    1048576          1 NO  INACTIVE                153302 2002年04月
         2          1        201    1048576          1 NO  INACTIVE                153435 2002年04月
         3          1        202    1048576          1 NO  CURRENT                 153436 2002年04月
         4          1        200    5242880          2 NO  INACTIVE                153434 2002年04月
/*****************************************************************************************************/

B. 删除日志文件组:
SQL> Alter database DROP logfile group n;

说明:(1)Current, Active组不得删除,如果是归档日志组,要求先归档,否则,该组状态为ACTIVE,不能删除。
(2) 数据库只有两个日志组时,不得删除。
(3) 逻辑删除后,再删除物理文件。切记:不要删除错了文件,尤其是在UNIX下,最好在删除之间检查正在使用的物理文件,(当然,如果删除之前先备份文件更好)如下命令:
SQL> select * from v$logfile;

C. 增加日志成员文件:
SQL> Alter database ADD logfile member '成员文件名及路径' to group n;

D. 删除日志成员文件:
SQL> Alter database DROP logfile member '成员文件名及路径';

说明:(1) Current, Active组的成员不得删除;
(2) 日志组只有一个成员时,不得删除成员,可以删除组。

3、控制文件(Control Files):是描述数据库结构的二进制文件。包括:
 。数据库名db_name
 。数据库创建的时间
 。全部数据文件名及路径
 。全部日志文件名及路径
 。数据库恢复时所需的同步信息
// 控制文件只需要一个,但在oradata目录下有三个,另两个是镜像,三个文件内容相同。

(1) 查询数据库跟踪文件信息(跟踪文件记录所有影响控制文件修改的命令):
D:/oracle/admin/db_name/bdump/SIDalrt.log // SID视具体情况而定
/u01/app/oracle/admin/db_name/bdump/alert_sid.log

// 这个文件时间长了之后会变得很大,因此需要定期删除。

(2) 建议设置:
 。至少设置两个控制文件并保存于不同的磁盘。
 。在数据库参数文件中的Control_files指明控制文件。
  . 控制文件可以镜像,可以在安装或者安装完成后进行配置
  .
 
[(2).C] 数据库参数文件名称及路径:
Unix:
/u01/app/oracle/admin/db_name/pfile/initSID.ora

Windows NT/2000:
D:/oracle/admin/db_name/pfile/init.ora

指明控制文件的参数:
control_files = ('file1', 'file2', 'file3')
例:
control_files = ( "D:/Oracle/oradata/ora54/control01.ctl",
    "D:/Oracle/oradata/ora54/control02.ctl",
    "D:/Oracle/oradata/ora54/control03.ctl")
   
(3) 查询控制文件名及路径:
SQL> select * from v$controlfile;

(4) 控制文控镜像方法:
A. 关闭数据库
B. 复制控制文件到目标路径
C. 修改参数文件control_files,包含新的控制文件
D. 重启数据库

[DBA的图形界面管理工具:DBA Studio]
启动DBA Studio, 选择“登录到Management Server”:
登录用户:sysman, 密码:oem_temp(默认,登录成功后要求修改)

在登录之前,要求Management Server服务已经启动,同时已经在系统控制台Console中搜索并增加(配置)了Management Server要管理的数据库。

二、逻辑结构:
数据库的逻辑结构包括:
。表空间(Tablespaces)
。段(Segments)
。区(Extents)
。数据块(Data Blocks)

数据块->区->段->表空间->(逻辑)数据库
(1) 表空间://对应四种不同的段类型,Oracle有四种对应的表空间
 。数据表空间
 。索引表空间: INDX
 。临时表空间: TEMP
 。回退表空间: RBS

(2) 段(Segments)的四种类型:
 。数据段:用来存储基表数据
 。索引段:存储索引数据
 。临时段:用于排序(Order by)、汇总等
 。回退段:用于事务回退,rollback语句使用

// 临时段和回退段占的空间固定,不能增大。
// Oracle中最复杂的就是回退段管理。
// 每个段的结构都大致相同,即包含若干个区,每个区的大小又是数据块的整数倍。
// 表空间是Oracle中最大的逻辑结构

1、表空间(Tablespaces):
(1)表空间的特点与作用:
。控制数据库数据磁盘分配

。跨越磁盘存储数据

。表空间通过离线(Offline)、在线(online)控制数据可用性。

[A]设置表空间offline、online、read only、read write属性:
SQL> Alter tablespace 表空间名 offline;
SQL> Alter tablespace 表空间名 online;  // 正常状态
SQL> Alter tablespace 表空间名 read only;
SQL> Alter tablespace 表空间名 read write; // 正常状态

[system表空间不得offline]

[B]查询表空间信息:
SQL> select * from dba_tablespaces;
SQL> select tablespace_name, status from dba_tablespaces;

。完成部分数据库的备份与恢复

。表空间通过数据文件来扩大,表空间大小等于构成该表空间的所有数据文件大小之和。

[A] 查询表空间与数据文件之间的关系:
SQL> select tablespace_name, file_name from dba_data_files;

2、段(Segments):
(1) 数据段:存储基表数据的段,由Create table命令产生。用户在创建基表时,则自动在用户缺省表空间中创建一个数据段。
[A]查询用户与用户缺省表空间对应关系:
SQL>select username, default_tablespace from dba_users;
[B] 查询表与所在表空间的对应关系:
SQL> select table_name, tablespace_name from user_tables;

如果一个表有分区,则用上面这个命令无法查询表所使用的表空间,因为表使用了多个表空间。查询方法如下:
SQL> select partition_name, segment_type, tablespace_naem from user_extents
 where segment_name = 'EMPLOYEE';

(2)、索引段:存储索引数据的段,由Create index命令产生。用户在创建索引时,则自动在用户缺省表空间中创建一个索引段。
[A] 索引与所在表空间的对应关系:
SQL> select index_name, tablespace_name from user_indexes;

[B] 使用索引表空间创建索引:
SQL> create index emp_job on emp(job) tablespace indx;
// 如果不加tablespace indx,则索引默认创建在用户缺省表空间中。

(3)临时段:用户排序、汇总时临时工作空间。临时段表空间在DBA创建用户时确定。创建用户时未指定临时表空间,则系统自动使用system表空间作为临时表空间使用。临时表空间公用(temp)。
[A] 查询用户及所使用的临时表空间:
SQL> select username, temporary_tablespace from dba_users;

// 建议不要使用system作为用户的临时表空间,因为容易导致碎片。

[B]DBA可以修改用户的临时表空间
SQL> Alter user 用户名 temporary tablespace temp;

(4) 回退段:用于用户在回退事务时使用。回退段由DBA创建,全体用户公用。
[A] 查询回退段及所对应的表空间:
SQL> select segment_name, tablespace_name, status from dba_rollback_segs;

[B]为什么要设回退段?
回退段是数据库的一部分,是Oracle 数据库的一个重要参数,其设计是否正确直接影响到数据库的动态性能。Rollback 段的使用用于保存一个事务的操作,以便在某些情况下回退或取消操作。 每个Oracle数据库都有多个回退段。

[C] 回退段的作用
。并发操作时,保证数据的读一致性。
。使用 SQL语句rollback回退一个事务的操作。
。事务恢复的需要。

[D]回退段操作举例
。由于语句错误回退一个事务。
。回退一个事务、或回退事务到一个保存点(SavePoint)。
。由于异常进程中断而回退。
。在例程恢复中回退所有未完成的事务。

// delete操作是最消耗回退段的操作

[E]回退段使用原则
。根据事务大小及数量确定回退段。 // 每四个用户至少对应一个回退段
。每个事务必须对应一个回退段。
。一个事务可以根据回退段中“最少使用原则”来自动对应一个回退段。
[C*]只有delete、insert、update三个命令使用回退段
// 回退段可以自动动态扩展,但不能无限扩展。

/* 如果回退段都已经被用户占用,那么再增加新用户,则新用户使用所有回退段中磁盘扩展量最小的回退段(与其它用户共 享使用),这就是“最少使用原则”。因此,回退段可以共享。
*/

。在创建数据库后,应为系统创建回退段,事务越多,回退段应越多。

3、区(Extents):区是磁盘空间分配最小单位。每一个区的大小都是数据块的整数倍(用户可以指定,默认是5倍)。

SQL> select segment_type, extent_id, bytes, blocks from user_extents where segment_name = 'EMP';
 
(1)区大小控制参数(磁盘存储参数):
// 下面这五个参数对磁盘存储有直接影响
Initial:初始区大小
Next: 增长区大小
Minextents:区的最小个数
Maxextents:区的最大个数
Pctincrease:区的增长百分比

SQL> Create table sales(
 s1 char(20),
 s2 char(20)
 Storage( initial 10K --// 第一个分区的大小
   next 10K  --// 第二个分区的大小
   minextents 1 --// 最少一个分区
   maxextents 121 --// 最多121个分区
   pctincrease 50); -- // 区的增长比例为50%。
以上语句中的Storage部分,在建表时如果不写是要隐含执行的。
1Block = 2K
第一个分区:Initial = 10K = 1Blocks * 5
第二个分区:Next = 10K
第三个分区= Next + next * 50% = 10K + 5K => 变成blocks的整数倍 = 16K
第四个分区 = 第三个分区 * ( 1 + 50%)
...

例:SQL> Create table sales(s1 char(20), s2 char(20)
  Storage(initial 100K next 200K minextents 2 maxextents 121 pctincrease 0);

/* 区太小,会导致区的数目太多,进一步导致磁盘碎片的产生。而区太大,则容易浪费空间。因此,要选择合适的分区大小。最好的办法是根据数据量的大小给表只分一个区。*/
估算分区的大小的方法:以上面例子中的表为例:
(1) 1 行 = 40B
(2) 1block = 2048B , 2048B - 2048 * 20% - 标识= 1547
// 2048 * 20% 表示给一个块儿留的剩余空间,标识是用来存储表中每行在块中的位置的信息,其大小可以通过查询V$type_size来获得
(3) 1547 / 40 = A
(4) 假设表中可能有1百万行的数据(最大数据量),则1000000/A*2K = B 兆。

则 initial 为 B兆, 此时next值不要太大,因为initial区中已经分配了足够的空间,假设是100M,那么可以把Next设置成1M。

(2) 区存储参数可以用于:表空间、表、段(回退段)、索引

(3) 存储参数优先使用原则:
实体级参数> 表空间级对应参数> 系统缺省参数

实体级参数:指建立实体(如建表)时指定的存储参数
表空间级对应参数:可以从dba_tablespaces数据字典中查询。

(4) 查询实体的存储参数:
SQL> select initial_extent, next_extent, min_extents, max_extents, pct_increase
 from user_tables
 where table_name = 'EMP';

[C* 有时SQL*Plus中查询某个字段较多的表时,屏幕宽度不够,而滚动条又不能横向滚动,此时修改环境变量中的arraysize参数,将缓冲区宽度修改一下,默认是1000,可以修改成500,保存设置后即可使用横向滚动条。]

(5)存储参数的修改:
SQL> Alter table emp
 Storage (next 200k maxextents 2000 pctincrease 50); -- // 五个参数中只有这3个能够修改

4、数据块(Blocks): 数据文件存储空间单位,I/O最小单位。数据块大小由参数db_block_size决定,数据库创建后不得修改。
(1)查询数据块大小:
SQL> select value from v$parameter where name = 'db_block_size';

[2002.05.13]
//=====================================================================================================================
三、内存结构:
1、系统全局区SGA(System Glbal Area):共享的系统内存区域。SGA由三部分组成:数据缓冲区、日志缓冲区、共享池。
(1) 数据缓冲区(Database Buffer Cache): 存储由磁盘数据文件读入的数据,所有用户共享。数据缓冲区大小由参数db_block_buffers确定。
 。数据缓冲区大小:db_block_buffers * db_block_size
 。参数文件位置:
 Windows NT: D:/oracle/admin/db_name/pfile/init.ora
 UNIX: /home/app/oracle/admin/db_name/pfile/initSID.ora
 
 // Dirty: 数据被修改而未写盘。Pinned: 未修改的数据
 。LRU( Least Recently Used): 最近最少使用原则
 
(2) 日志缓冲区(Log Buffer Cache): 存储数据库修改信息,由LGWR将日志缓冲区数据写入磁盘日志文件组。
 。大小由参数log_buffer确定
 
(3) 共享池(Shared Pool): SQL 缓冲区及数据字典区。对于SQL、PL/SQL程序进行语法分析、编译的内存区域。
 。大小由参数SHARED_POOL_SIZE来确定。(在参数文件中,单位为字节)
 。分三部分:Libary cache, Data Dictionary cache, UGA(User Global Area)
 。
 
 [C*] SQL 语句执行计划:
  Rule_Based: 基于规则,只考虑语句运行效率,不考虑成本。
  Cost_Based: 基于成本,考虑代价,硬件资源占用小。
。SGA = db_block_buffers * db_block_size + log_buffer + shared_pool_size

[在实用情况中,SGA当然是越大越好,但最大不要超过系统可用内存的55%~57%。]

。查询SGA及数据参数取值:
SVRMGR> show sga
SVRMGR> show parameter
SVRMGR> show parameter db
SVRMGR> show parameter log
SVRMGR> show parameter 参数名称

SQL> select * from v$sga;
SQL>select * from v$sgastat;

查询数据库名称:SQL> select name from v$database;
查询数据库实例名称:SQL> select instance_name from v$instance;

2、程序全局区PGA(Pragram Global Area): 非共享区域,主要是用户编程时变量、数组工作区域。

3、排序区SORT AREA:用户使用order by排序、汇总时临时工作区域。排序区大小由参数SORT_AREA_SIZE确定。

4、大区(Large Pool): 使用于数据备份工具Rman, 只用在Oracle8以上的版本数据库,大区的大小由参数:Large_Pool_size确定。

5、Java语言区(Java Pool): 用于Oracle 8i、Oracle9i中的Java语言。Java区的大小由参数Java_Pool_Size确定。

四、Oracle 实例的进程结构:
1、什么是Oracle实例?
  数据库启动时,系统分配SGA内存区域,同时启动后台进程,该SGA与后台进程合称为一个Oracle实例(Instance)。
Instance ==> SGA + Background Processes

数据库与实例相联系,有一个数据库就有一个实例。实例名用参数instance_name表示,数据库名用参数db_name表示。

。数据库实例名:
 instance_name (Oracle参数)
 ORACLE_SID(操作系统环境变量)
 在Unix系统中选择数据库实例:
 $ORACLE_SID=ora8i
 $export ORACLE_SID
 存取另一个数据库时:
 $ ORACLE_SID=ora835
 $ export ORACLE_SID
 $ svrmgrl
 在Windows NT/2000中选择数据库实例:
 c:/> set ORACLE_SID=ora8i
 C:/> svrmgrl
 C:/> set ORACLE_SID=ora835
 C:/> svrmgrl
 [*] 在Windows NT/2000中,数据库实例名定义在注册表中。
 
2、Oracle实例的进程结构:
 Oracle进程:单进程
    多进程==> 用户进程、服务器进程、后台进程。
 Dnnn(Dispatcher): 调度进程
 ARCH:归档进程
 PMON: 进程监控
 SMON: 系统监控
 CKPT: checkpoint
 RECO: Recovery
 
 [*] 进程数量的限制参数:Processes,Oracle数据库进程数Processes < Unix 操作系统核心参数SEMMNS(这个参数指定Unix的最大进程数)。
 
 // 查询后台进程及说明
 SQL> select name, description from v$bgprocess;
(1) 用户与服务器进程
 。用户进程(User Precess)在用户运行应用程序时自动产生。

[*] 数据存取方法:
a. 用户发出查询命令,产生user进程,server进程查找内存。
b. server 进程在内存没有找到数据时,则server进程从数据文件中读数据,则server进程在LRU找空闲块。
c. 将LRU中的dirty块--> Dirty List
d. Dirty List超长(threshold), 通知DBWR刷新缓冲区。
e. 从磁盘读数据进入空闲内存。

(2) 后台进程:
 [A]DBWR:数据写入进程。该进程将数据缓冲区数据写入磁盘数据文件,是进行数据缓冲区管理的后台进程。
 
 设置DBWR进程数量参数:DB_WRITE_PROCESSES=1-10
 进程名称依次为:DBW0, DBW1, ... DBW9
 
 [B]LGWR:日志写入进程。将日志缓冲区日志信息写入磁盘日志文件组,在日志切换时,再将日志信息由归档进程ARCH写入磁盘或磁带,产生归档日志。一个数据库只有一个LGWR日志写入进程。
 
 [C]PMON(Process Monitor): 进程监控。在用户进程中断时,负责清理该用户所占用的硬件资源。
 
 [D]SMON(System Monitor):系统监控。负责清理用户不再使用的临时段。
 
 [E]ARCH:归档进程。该进程在日志切换时,负责将日志信息写到指定的磁盘存储目录,产生归档日志,是与数据库备份有关的一个后台进程。在缺少状态下该进程不存在(因为oracle默认安装状态为下日志为非归档方式)。
 [*] 与ARCH有关的数据库参数:
 。启动归档进程参数:log_archive_start=true (缺省为false)
 。确定归档日志文件磁盘存储目录:log_archive_dest=目录名
 log_archive_dest=/home/oracle/archive
 log_archive_dest=d:/oracle/archive
 。确定归档文件存储格式:log_archive_format=%t.%s.arc  
 /* %t:表示线程号 %s:表示日志序列号,这样文件不会同名。可以不要%t, 扩展名自己给,也可以不要扩展名。如%s.log。如果写成%S(大写的S),则文件名前面加零对齐。如123.log 会变成00123.log这种形式。*/
 
 。确定归档日志文件镜象目录:
 log_archive_duplex_dest=镜像目录名 (Oracle8以上)
 log_archive_duplex_dest=/home1/oracle/archive
 
 。Oracle8i启用新的日志文件存储目录:
 log_archive_dest_n = 'Location=目录名'(Oracle8i以上) n<=5 // 在oracle9i,n <= 10
 
 log_archive_dest_1 = 'location=/home1/oracle/archive'
 log_archive_dest_2 = 'location=/home2/oracle/archive'
 ...
 log_archive_dest_5 = 'location=/home5/oracle/archive'
 
 [注意:]归档日志存储目录要么为2个,即使用dest and duplex_dest这种方式,要么为5个,即使用dest_n这种方式,两种方式不能混用。
 
 。失效参数(Oracle8i):
 log_archive_dest_state_n=DEFER(失效)
 log_archive_dest_state_n=ENABLE(生效)
 
 //使相应目录失效:log_archive_dest_state_1 = DEFER
 [*]也可以在线设置失效:SQL> alter system set log_archive_dest_state_1=defer;
 
 。启动多个归档进程参数:log_archive_max_processes = 1~10  //要启动几个就写几
 归档进程名称依次为:ARCH0, ARCH1, ... ARCH9
 
 // 以上参数查询请在svrmgrl中使用:show parameter log
 
 [SVRMGR> shutdown abort 是比shutdown immediate更有效的关闭数据库的命令]
 
 [F] CKPT:检验点(Checkpoint)进程,用来同步各个数据文件。Checkpoint_Change#。
 
 a. checkpoint产生的六个条件[参考PowerPiont教程:dba_结构.ppt P61]。
 
 // DBA强制产生检验点:SQL> alter system checkpoint;
 
 b. 检验点的几个参数
/* SVRMGR> show parameter checkpoint
NAME                                TYPE    VALUE
----------------------------------- ------- ------------------------------
log_checkpoint_interval             ??    10000
log_checkpoint_timeout              ??    1800
log_checkpoints_to_alert            ???  FALSE
*/

五、Oracle连接配置结构

3、多线程服务器体系结构MTS(Multithreaded Server)

SVRMGR> show parameter mts;

[第二章 数据库启动与关闭]

一、数据库启动:
Unix:
 login: oracle
 Password: xxxx
 $
 $ORACLE_HOME: /home/app/oracle/product/8.1.7
 $ svrmgrl
 SVRMGR>connect internal
 SVRMGR> startup
 SVRMGR> exit
 [*]启动监听进程:
 $lsnrctl start
 如果在启动时报错,检查:/home/app/oracle/product/8.1.7/network/admin/listener.ora
 $lsnrctl stop  // 停止监听进程
 $lsnrctl status  // 显示监听进程状态
 
二、数据库启动过程:
1、启动数据库实例: ORACLE instance started
 。读取参数文件
 。分配SGA区
 。启动后台进程
 // 如果启动出现问题,有可能是因为参数文件有问题或者内存不足。
2、数据库安装:Database mounted
 。读取控制文件
 。打开控制文件
 // 如果启动出现问题,可能是控制文件出现问题。
3、打开数据库:Database opened
 。打开全部数据文件
 。打开全部日志文件
 // 如果有一个文件出现问题,则数据库不能启动。
 
数据库文件读取顺序:参数文件 ==> 控制文件 ==> 日志、数据文件,三类文件中不能有一个文件损坏,否则数据库不能启动。

4、数据库启动过程中可以使用的选项:

SVRMGR> startup OPEN --1、2、3 // 加OPEN与不加OPEN效果相同,1、2、3指三个步骤:启动实例 ==> 安装数据库 ==> 打开数据库
SVRMGR> startup MOUNT --1、2 启动实例=> 安装数据库
SVRMGR> startup NOMOUNT -- 1  只启动数据库实例

(1) OPEN用于数据库的正常启动(或不加OPEN)。
(2) MOUNT的使用方式:
 。用于修改数据库归档方式
 。用于数据库恢复。Recovery命令在mount状态使用。
在mount状态,所有v$xxxx 数据字典可以使用,所有alter database命令可以使用。

(3) NOMOUNT的使用方式:
 。创建控制文件
 。创建新的数据库
 
(4) 数据库在MOUNT下可以使用的选项:
SVRMGR> startup MOUNT
SVRMGR> Alter database ARCHIVELOG;  // 将数据库由非归档方式修改为归档方式
[*] SVRMGR> Alter database NOARCHIVELOG; // 将数据库由归档方式修改为非归档方式
// SVRMGR> archive log list
// SVRMGR> select log_mode from v$database;
SVRMGR> Alter database OPEN;   // 将数据库由MOUNT直接到OPEN状态。
SVRMGR> Alter database OPEN READ ONLY; // 整个数据库以只读方式打开
SVRMGR> Alter database OPEN READ WRITE; // 整个数据库以读写方式打开(系统缺省方式,不需要写上READ WRITE)

[2002.05.14]
//=====================================================================================================================

(5) 数据库在OPEN下可以使用的选项:
[A]
SVRMGR> startup PFILE=参数文件名称及路径

// 在有两个数据库存在的情况下,可以用如下方法同时启动两个数据库。
SVRMGR> startup PFILE=第一个数据库的参数文件名称及路径
SVRMGR> startup PFILE=第二个数据库的参数文件名称及路径

[B]
SVRMGR> startup RESTRICT // 限制性数据库启动命令,以这种方式启动数据库后,具有restricted session权限的用户可以连接数据库,其他用户不能连接。

DBA可以指定用户连接:
SQL> grant restricted session to scott;  // 指定权限
SQL> revoke restricted session from scott; // 收回权限

修改限制:
SQL> Alter system disable restricted session; // 解禁
SQL> alter system enable restricted session;  // 禁止

[C]
SVRMGR> startup FORCE // 强制性数据库启动命令

[D*] 允许多个选项同时使用,顺序没有关系:
SVRMGR> startup PFILE=c:/init.ora FORCE MOUNT
SVRMGR> startup force restrict pfile=c:/init.ora

三、数据库关闭命令:
在关闭服务器之前,必须使用shutdown命令先关闭数据库,再关闭操作系统。

SVRMGR> shutdown normal  // 正常关机。系统等待所有用户从数据库中正常退出,很难关掉。
SVRMGR> shutdown immediate // 立即关机。中断现在连接,回退未提交事务,不再接收用户的连接请求。(有的用户数据会丢失)
SVRMGR> shutdown abort  // 异常关机。只关闭实例,释放内存,不保证数据完整性。尽量少用。
SVRMGR> shutdown transactional // 事务终结后关机。等待用户提交数据后关闭数据库。

[补充内容]
四、数据库启动过程中失败恢复方法:

1、第一步不启动(实例):参数文件错误:参数错误、路径、文件名、参数设置错误等。

2、第二步不能mount:控制文件坏。检查有没有镜像文件,如果没有,需要重新创建控制文件。

3、第三步,数据库不能Open。数据文件或日志损坏。

(1) 数据文件(Datafile)被破坏或被误删除时数据库的恢复方法。
SVRMGR> startup mount

[A]如果数据库运行在ARCHIVELOG模式下,使用以下命令:
SVRMGR> alter database datafile '被删数据文件名及路径' OFFLINE;
// 在归档方式下,这个被删的文件可能通过归档日志恢复数据。

打开数据库:SVRMGR> Alter database open;

[B]如果数据库运行在NOARCHIVELOG模式下,使用以下命令:
SVRMGR> alter database datafile '被删数据文件名及路径' OFFLINE DROP;
// 在非归档方式下,被删数据文件的内容绝对不可能恢复,所以只好DROP掉。

打开数据库:SVRMGR> Alter database open;

(2) 日志文件(Redo Log Files)被破坏或被误删除时数据库的恢复方法。
SVRMGR> startup mount

删除被物理破坏的日志文件组:
SVRMGR> Alter database drop logfile group n;

增加已经被物理破坏的日志文件组:
SVRMGR> Alter database add logfile group n('日志成员文件', '日志成员文件') size xxM;

SVRMGR> Alter database open;

// 如果当前日志被破坏,则恢复操作将比较复杂,必须通过数据库备份来恢复(不完全恢复)。

4、重新创建控制文件(Control Files):
创建控制文件的语法:
SVRMGR> startup nomount
    Create controlfile database 数据库名称
    logifle
    group 1 (日志文件名及路径'', '日志文件名及路径') size xxM,
    group 2 (日志文件名及路径'', '日志文件名及路径') size xxM,
    ...
    noresetlogs
    datafile
    '第一个数据文件名称及路径' size xxM,  // xxM中不能出现小数点儿,如果有小数,就使用K,如果仍然有小数,则使用字节。
    '第二个数据文件名称及路径' size xxM,
    ...
    character set zhs16gbk;
   
SVRMGR> startup nomount
  Create controlfile database ora8i
  logfile
  group 1 ('d:/oracle/oradata/ora8i/redo01.dbf') size 1M,   
  group 2 ('d:/oracle/oradata/ora8i/redo02.dbf') size 1M,
  group 3 ('d:/oracle/oradata/ora8i/redo03.dbf') size 1M,
  noresetlogs
  datafile
  'd:/oracle/oradata/ora8i/system01.dbf' size 70M,
  'd:/oracle/oradata/ora8i/rbs01.dbf' size 520M,
  ...
  character set zhs16gbk;

SQL> select bytes/1024/1024, blocks, file_name from dba_data_files;
// 通过这个命令来查询数据文件的大小,以Oracle中查询的数据为准,不要根据操作系统显示的文件大小来决定,建议事先做好备份。

[*C] 修改数据库名称时,需要重新创建数据库控制文件,语法如下(注意与上面的语法稍有不同):
SVRMGR> startup nomount
    Create controlfile set database 新数据库名称  // 这一行有不同,注意:数据库的名称一般不要超过5个字符。
    logifle
    group 1 (日志文件名及路径'', '日志文件名及路径') size xxM,
    group 2 (日志文件名及路径'', '日志文件名及路径') size xxM,
    ...
    resetlogs       // 这一行也有不同
    datafile
    '第一个数据文件名称及路径' size xxM,  // xxM中不能出现小数点儿,如果有小数,就使用K,如果仍然有小数,则使用字节。
    '第二个数据文件名称及路径' size xxM,
    ...
    character set zhs16gbk;
   
五、检测数据库文件工具:DBVerify

使用方法:
C:/> dbv file=文件名及路径 logfile=输出结果文件名 blocksize=数据块大小(缺省是2K,否则指出) start=起始数据块 end=终止数据块

可以检测数据、日志及控制文件等。如果不加start 和 end,则默认检测整个数据文件。

[第三章 Oracle在Unix下安装]

一、创建数据库安装用户

*1、Oracle在Unix下运行平台:
 。Sun Solaris(Sun SPARC)(Solaris是Oracle目前运行最多的平台)
 。HP-UX
 。IBM-AIX
 。COMPAQ Tru64-Unix(ALPHA)
 。SCO UNIX(PC)
 。Linux(PC)
 。SGI
 // 前三种平台上运行的最多

*2、用户组名:dba(Oracle7, Oracle8)
  oinstall(Oracle8i, Oracle9i)

*3、在Unix下,与用户所在组有关的文件:/etc/group
如果要加新组就在此文件中新加一行,如:
oinstall::20:oracle,oraweb
// gid < 1024,组号越大,权限越小。

*4、与用户有关的文件:/etc/passwd
oracle8i:x:30:20:Oracle8i for Unix:/u01/app/oracle/product/8.1.7:/bin/sh
用户名:x:用户号:组号:描述(可省略):文件系统名称:shell

//# admintool  Sun的图形管理工具
//# sam   HP-UX
//# scoadmin  SCO UNIX

二、创建Oracle数据库安装目录
在Unix下安装数据库,最好使用Oracle建议设置的标准目录:
OFA(Optimal Flexible Architecture):将Oracle的系统文件与数据库文件分别存储。

OFA要求创建两个目录:
$ORACLE_BASE
$ORACLE_HOME

假设目录为:/u01/app/oracle/product/8.1.7
则:$ORACLE_BASE = /u01/app/oracle    // 这个目录下的各个子目录存放数据库文件
$ORACLE_HOME = /u01/app/oracle/product/8.1.7  // 这个目录存储系统文件

例如:$ORACLE_BASE/oradata存储数据文件

$df -k // 查看文件系统的使用率,如果超过80%,就不要再继续添加文件,否则文件系统将十分慢

#mkdir app
# cd app
# mkdir oracle
...
# mkdir 8.1.7

# chgrp -R oinstall oracle //-R包括子目录,将oracle目录的属组改为oinstall组
# chown -R oracle oracle  // 将oracle(第二个)目录的属主改为oracle用户

# ls -al

三、编辑安装用户的.profile文件,定义操作系统环境变量

NLS_LANG,Oracle用户在安装时默认安装为与操作系统一致的字符集,因此要想在英文版本的操作系统上安装支持中文的Oracle时,务必要设置这个环境变量。

#vi .profile // 内容如下:
ORACLE_BASE=/u01/app/oracle
export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/8.1.7
export ORACLE_HOME
ORACLE_SID=ora8i  // 数据库实例名
export ORACLE_SID
ORACLE_TERM=sun  //终端类型,SCO为vt100,防止字符混乱
export ORACLE_TERM
NLS_LANG="simplified chinese"_china.zhs16gbk (oracle8.0以后)
       .zhs16cgb231280(oracle 8以前,为保持数据兼容,如要导入oracle7的数据,建议选择这一个)
export NLS_LANG
LD_LIBRARY_PATH=/usr/lib:$ORACLE_HOME/lib
export LD_LIBRARY_PATH
ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
export ORA_NLS33
TMPDIR=/var/tmp
export TMPDIR
PATH=/bin:$ORACLE_HOME/BIN:/usr/sbin;/opt/bin
export PATH

// .profile文件应该放在$ORACLE_HOME目录下。

四、配置操作系统核心

五、安装过程:
在安装光盘下运行:$./runInstall

[第四章 创建Oracle数据库、表空间管理、回退段管理]

一、创建数据库
1、确定数据库名、实例名、服务名
数据库名参数:db_name = prod
数据库实例名参数:instance_name = prod
域名:db_domain
数据库服务名参数:service_names = prod[.域名] //服务名等于:数据库名.域名,为了省事,一般不要域名。

2、创建新数据库的参数文件:init.ora

需要修改的参数:
db_name
instance_name
service_names
control_files : d:/oracle/oradata/prod/... 01 02 03
background_dump_dest: 后台信息跟踪文件的存储位置d:/oracle/oradata/prod/bdump
user_dump_dest: 用户信息跟踪文件的存储位置d:/Oracle/oradata/prod/udump
sql_trace = true

3、设置操作系统参数:主要是设置ORACLE_SID选择数据库实例
在Unix下设置实例的方法:
$ORACLE_SID=ora8i
$export ORACLE_SID

换成另外一个:
$ORACLE_SID=prod
$export ORACLE_SID

在Windows NT/2000下,有一个实例写在注册表中,如果要进入第二个数据库,设置方法如下:
C:/> set ORACLE_SID=ora8i
C:/> set ORACLE_SID=prod

// 为了不致发生混乱,每次在使用数据库之前,进行上述设置。

4、创建数据库实例
语法:C:/>oradim -new -sid [实例名] -intpwd [口令] -startmode auto -pfile [数据库参数文件名称及路径]

。红色部分需要用户确定
 。startmode: auto, manual
 。参数文件名称及路径:
 Unix:
  /u01/app/oracle/admin/db_name/pfile/initSID.ora
  /u01/app/oracle/product/8.1.7/dbs/initSID.ora // 这是oracle直接读取的参数文件
 // 在Unix中上面的dbs目录是pfile目录的symbol link,即两上文件是同一个文件。
 Windows:
  d:/oracle/admin/db_name/pfile/init.ora
  d:/oracle/ora81/database/initSID.ora   // 这是oracle直接读取的参数文件
 /*第二个文件指向第一个文件,上面这个文件可以随便放到什么位置,只要在第二个文件中通过IFILE指明了其位置,也可以直接用第一个文件的内容替换第二个文件的内容。*/
 
[*] 删除数据库实例方法:
D:/> oradim -delete -sid [实例名]
 
最后的命令格式为:
D:/> oradim -new -sid prod -intpwd prod -startmode auto -pfile d:/oracle/ora81/database/initprod.ora

[如果执行了set oracle_sid=prod后,仍然不能通过svrmgrl连接到internal用户,请检查是否在注册表中设置了local串。]

5、创建数据库:
SVRMGR> startup nomount
SVRMGR> create database prod
  logfile group 1('d:/oracle/oradata/prod/log1a.log',
     'd:/oracle/oradata/prod/log1b.log') size 2m,
      group 2('d:/oracle/oradata/prod/log2a.log',
     'd:/oracle/oradata/prod/log2b.log') size 2m
  datafile 'd:/oracle/oradata/prod system01.dbf' size 200m
   autoextend on next 10m maxsize 1000m
  character set zhs16gbk;

[2002.05.15]
//=====================================================================================================================
 
6、加载数据字典:
(1) 加载常用的数据字典:
SVRMGR>@d:/Oracle/ora81/rdbms/admin/catalog
SVRMGR>@/u01/app/oracle/product/8.1.7/rdbms/admin/catalog

(2) 加载PL/SQL程序包:
SVRMGR>@d:/Oracle/ora81/rdbms/admin/catproc

(3) 加载Java程序包:
SVRMGR> @d:/oracle/ora8i/javavm/install/initjvm

7、网络配置:
配置tnsnames.ora文件
d:/oracle]ora81/network/admin/tnsnames.ora

8、以system登录数据库,加载资源文件profile:
SQL> @d:/oracle/ora81/sqlplus/admin/pupbld.sql

//如果不运行这个sql程序,普通用户登录时会提示错误。

[C*] 对于新数据库,监听程序不用配置,如果运行中出现没有监听,则运行:
D:/> lsnrctl status
查看相应的数据库是否已启动监听。如果没有启动监听,运行:
D:/> lsnrctl stop
D:/> lsnrctl start
重启监听程序。

如果在SQL*Plus中登录数据库时,提示service_name丢失,则重启数据库。

SQL> select name from v$database; //查询当前数据库

[C*]在Unix下:$dbassist

在Windows NT/2000下(oracle8i):
程序组-> Database administration-> Database Configration Assistant

可以删除已创建的数据库(服务、文件)。

通过提示符下命令:oradim -delete -sid prod -srvc oracleserviceprod

SVRMGR> show parameter license   // 查看最大会话数,0表示没有限制

共享服务器连接模式:
最大  缺省    说明
65534 254    最大数据库文件数
254  32    最大日志文件数
5  2    最大日志成员数

二、表空间管理

SQL> select * from dba_free_space;  // 查询表空间是否存在碎片

1、创建表空间
(1)语法:SQL> Create Tablespace tablespacename
   Datafile 'filespec' Attributes
   Default Storage
   Online/offline;

(2)实例:
SQL> Create tablespace sales_2002
 datafile
 'D:/oracle/oradata/ora8i/sales_2002_01.dbf' size 100m,
 'D:/Oracle/oradata/ora8i/sales_2002_02.dbf' size 100m
 autoextend on next 100m maxsize unlimited,   // 每个文件都可以加上这一行,表空间的扩展属性
 'D:/oracle/oradata/ora8i/sales_2002_03.dbf' size 100m
 default storage(initial 100k
     next 100k
     minextents 1
     maxextents unlimited
     pctincrease 0);
    
    
(3)查询表空间与数据文件对应关系:
SQL> select tablespace_name, bytes, blocks, autoextensible, file_name from dba_data_files;

(4)创建临时表空间:在创建表空间时增加临时表空间关键字:temporary

SQL> Create tablespace temp_data datafile 'd:/oracle/oradata/ora8i/acc01.dbf' reuse
default storage(initial 100k next 100k minextents 1 maxextents unlimited pctincrease 0)
TEMPORARY;

说明:A.上例中的reuse指在相应的目录已经存在一个acc01.dbf(大小已经确定,例如一个被删除的表空间,但物理文件未被删除),则按这个文件的大小新建文件,内容将被覆盖。如果文件不存在,需要使用size来确定大小。

B. 临时表空间用于排序,在创建用户时可以为用户指定专用的临时表空间。临时表空间不得用于创建永久性实体(例如表)。
SQL> create table aa(c1 number(10)) tablespace sales_2002;
SQL> create table bb(c1 number(10)) tablespace temp_data;

C. 查询表空间类型:SQL> select tablespace_name, contents from dba_tablespaces;

2、改变表空间:

(1)为表空间增加数据文件:
SQL> Alter tablespace sales_2002 ADD
 datafile
 'd:/oracle/oradata/ora8i/sales_2002_04.dbf' size 10m,
 'd:/oracle/oradata/ora8i/sales_2002_05.dbf' size 10m
 autoextend on next 50m maxsize 1000m;

(2) 将数据文件从一个磁盘移动到另一个磁盘
 。将表空间脱机offline
  SQL> Alter tablespace sales_2002 offline;
 。物理移动:将要移动的表空间文件复制或移动到目的磁盘
 。逻辑移动
  SQL> alter tablespace sales_2002
   rename datafile
   'd:/oracle/oradata/ora8i/sales_2002_04.dbf',
   'd:/oracle/oradata/ora8i/sales_2002_05.dbf'
   to
   'c:/sales_2002_04.dbf',
   'c:/sales_2002.05.dbf';
 。将表空间联机online
  SQL> alter tablespace sales_2002 online;
 
其中,system表空间数据文件不得移动。

(3) 修改表空间的缺省存储参数

SQL> alter tablespace sales_2002
 default storage(
 initial 1m
 next 1m
 minextents 2
 maxextents 200
 pctincrease 50);
 
3、删除表空间
SQL> Drop tablespace 表空间名;  // 空的表空间。
SQL> Drop tablespace 表空间名 INCLUDING CONTENTS;  // 如果表空间中已经建表,必须加Including contents参数。

删除表空间后,再物理删除相应的表空间文件,一定要确认是否删除了正确的物理文件,在UNIX下,任何文件对root用户来说都没有保护措施,可以随便删除。

三、Oracle8i启用本地化管理(Locally Managed Tablespaces):
表空间类型:数据字典管理表空间,本地化管理表空间

本地化管理表空间自动消除磁盘碎片

SQL> create tablespace account datafile 'd:/oracle/oradata/ora8i/acc01.dbf' 10m
 default storage(initial 40k next 40k minextents 1 maxextents 121 pctincrease 0);
 
SQL> Alter database datafile 'd:/oracle/oradata/ora8i/acc01.dbf' resize 50m;

SQL> Alter tablespace account coalesce;  // 磁盘碎片合并命令。

1、区大小相同
SQL> Create tablespace account
 datafile 'd:/oracle/oradata/ora8i/acc01.dbf' size 10m,
 'd:/oracle/oradata/ora8i/acc02.dbf' size 10m
  extent management local uniform size 50k;
// extent management local: 区本地化管理;uniform:每个区大小相同,如果不指定size,size默认是1m

对于实行本地化管理的数据文件仍然可以使用autoextend on next, maxsize等参数。

查询表空间类型及区管理方式:
SQL> select tablespace_name, extent_management, allocation_type from dba_tablespaces;

2、区大小由系统自动分配相同(系统缺省方式)
SQL> Create tablespace finance
 datafile
 'd:/oracle/oradata/ora8i/fina01.dbf' size 10m
 extent management local autoallocate;   // 缺省状况是autoallocate,如果只写extent management local。

<=等价=>
SQL> Create tablespace finance
 datafile
 'd:/oracle/oradata/ora8i/fina01.dbf' size 10m
 extent management local;
 
表大小  区大小
64K   64K
1m   1m
64m   8m
1000m  64m

3、创建本地化管理临时表空间
SQL> Create temporary tablespace temp1
 tempfile
 'd:/oracle/oradata/ora8i/temp1_01.dbf' size 10m
 extent management local uniform size 10k;
 
[临时表空间不得使用AutoAllocate选项,就算不写uniform,默认也是uniform]
 
SQL> select tablespace_name, extent_management, allocation_type from dba_tablespaces;

[2002.05.16]
//=====================================================================================================================
四、回退段管理
1、创建回退段:rbs

[*]手动创建数据库后,必须先创建回退段表空间:
SQL> create tablespace rbs
 datafile 'd:/oracle/oradata/ora8i/rbs01.dbf' size 50m;

[*]创建回退段:
SQL> Create rollback segment rs01
 tablespace rbs
 storage(initial 40k next 40k
 minextents 2      // 最少是2,不能是1
 maxextents 121
 optimal 120k);  // optimal值的大小至少比2个区的大小要大才有意义,在本例中要大于80K。
 
回退段的工作过程:(80K不够用了)扩张->(使用结束)回缩到Optimal值 ->(120K不够用了)再扩张。

新建回退段的缺省状态是offline.

SQL> Create rollback segment rs02 tablespace rbs; // 如果不加storage参数,则各参数取缺省值(即表空间的相关值)

[*]查询回退段信息:
SQL> select segment_name, tablespace_name, status from dba_rollback_segs;

[*]回退段的设计方法:
A. 使用create rollback segment 创建多个回退段,至少四个事务平均一个回退段
B. 修改参数文件,将创建的回退段写入下列参数:rollback_segments=(rs01,rs02,...)
C. 重新启动数据库

[*]创建公共回退段:
SQL> create public rollback segment rs10 tablespace rbs;

修改公共回退段,使公共回退段online:
SQL> alter rollback segment rs10 online;

公共回退段不需要修改参数文件即可online。

查询:SQL> select segment_name, tablespace_name, status, owner from dba_rollback_segs;

2、修改回退段

SQL> Alter rollback segment 回退段名 online/offline; //对于私有回退段来说,只是临时修改,下次数据库启动时,只有参数文件中的回退段是online

3、删除回退段
A. offline
B. SQL> drop rollback segment 段名;
C. 如果是私有回退段,需要将其从参数文件中去掉。

// 无论是公共回退段还是私有回退段,都是系统共用的回退段。即作用相同。

[第五章 Oracle 数据库用户管理]

// PowerPoint讲义:DBA_用户.PPT

一、创建用户的Profile文件
SQL> create profile student limit  // student为资源文件名
 FAILED_LOGIN_ATTEMPTS  3  //指定锁定用户的登录失败次数
 PASSWORD_LOCK_TIME 5  //指定用户被锁定天数
 PASSWORD_LIFE_TIME 30  //指定口令可用天数
 ...
 [参考讲义:P6-P7]

二、创建用户
SQL> Create User username
 Identified by password
 Default Tablespace tablespace
 Temporary Tablespace tablespace
 Profile profile
 Quota integer/unlimited on tablespace;

例:
SQL> Create user acc01
 identified by acc01   // 如果密码是数字,请用双引号括起来
 default tablespace account
 temporary tablespace temp
 profile default
 quota 50m on account;
SQL> grant connect, resource to acc01;

[*] 查询用户缺省表空间、临时表空间
SQL> select username, default_tablespace, temporary_tablespace from dba_users;

[*] 查询系统资源文件名:
SQL> select * from dba_profiles;
资源文件类似表,一旦创建就会保存在数据库中。

/********************************************************************************************
SQL> select username, profile, default_tablespace, temporary_tablespace from dba_users;

SQL> create profile common limit
 failed_login_attempts 5
 idle_time 5;
 
SQL> Alter user acc01 profile common;

**********************************************************************************************/

三、修改用户:
SQL> Alter User 用户名
 Identified 口令
 Default Tablespace tablespace
 Temporary Tablespace tablespace
 Profile profile
 Quota integer/unlimited on tablespace;
 
1、修改口令字:
SQL>Alter user acc01 identified by "12345";

2、修改用户缺省表空间:
SQL> Alter user acc01 default tablespace users;

3、修改用户临时表空间
SQL> Alter user acc01 temporary tablespace temp_data;

4、强制用户修改口令字:
SQL> Alter user acc01 password expire;

5、将用户加锁
SQL> Alter user acc01 account lock;  // 加锁
SQL> Alter user acc01 account unlock;  // 解锁

四、删除用户
SQL>drop user 用户名;  //用户没有建任何实体
SQL> drop user 用户名 CASCADE;  // 将用户及其所建实体全部删除

*1. 当前正连接的用户不得删除。

五、监视用户:
1、查询用户会话信息:
SQL> select username, sid, serial#, machine from v$session;

2、删除用户会话信息:
SQL> Alter system kill session 'sid, serial#';

3、查询用户SQL语句:
SQL> select user_name, sql_text from v$open_cursor;

/***************************************************************************************************************************
SQL> ALTER SESSION SET
 NLS_LANGUAGE= 'SIMPLIFIED CHINESE'
 NLS_TERRITORY= 'CHINA'
 NLS_CURRENCY= 'RMB'
 NLS_ISO_CURRENCY= 'CHINA'
 NLS_NUMERIC_CHARACTERS= '.,'
 NLS_CALENDAR= 'GREGORIAN'
 NLS_DATE_FORMAT= 'yyyy-mm-dd dy'
 NLS_DATE_LANGUAGE= 'SIMPLIFIED CHINESE' 
 NLS_SORT= 'BINARY'
 TIME_ZONE= '+08:00'
 NLS_DUAL_CURRENCY = 'RMB'
 NLS_TIME_FORMAT = 'HH.MI.SSXFF AM'
 NLS_TIMESTAMP_FORMAT = 'DD-MON-RR HH.MI.SSXFF AM'
 NLS_TIME_TZ_FORMAT = 'HH.MI.SSXFF AM TZH:TZM'
 NLS_TIMESTAMP_TZ_FORMAT = 'DD-MON-RR HH.MI.SSXFF AM TZH:TZM'
***************************************************************************************************************************/

[第六章 Oracle权限与角色管理]

一、Oracle 权限管理
SQL> grant connect, resource, dba to acc01;

SQL> revoke connect, resource from acc01;

二、Oracle 角色管理(参考讲义)

SQL> Create Role <role_name>
 Identified by password/ Not Identified;
 
SQL> Alter Role <role_name> ...

SQL> Grant <privs> to <role_name>;

SQL> Grant <role_name> to <user_name>

SQL> Set Role <role_name>
 All Except <role_name2> / None  // 使角色生效或失效

[第七章 Oracle 数据库备份与恢复]

一、Oracle归档方式

确认数据库归档方式:

SVRMGR> archive log list;

SQL> select log_mode from v$database;

二、Oracle归档方式配置步骤:

1、启动自动归档进程ARCH
 log_archive_start=true
 
2、确定归档日志文件存储目录
 log_archive_dest=目录名

3、确定归档日志文件存储格式
 log_archive_format=%t_%s.arc

4、确定归档日志文件镜像目录:
 log_archive_duplex_dest=镜像目录名

5、以MOUNT方式启动数据库,修改数据库归档方式:
 SVRMGR> connect internal
 SVRMGR> startup mount
 SVRMGR> alter database archivelog;
 SVRMGR> alter database open;
 
// 前面1、2、3、4四个参数都在参数文件中。

[*]在Oracle8i以后,可以使用多个镜像目录:[8i最多是5个,9i是10个,与duplex方式不能混用]
log_archive_dest_1='location=d:/oracle/archive1'
log_archive_dest_2='location=d:/oracle/archive2'
log_archive_dest_3='location=d:/oracle/archive3'

[*]归档文件的格式为二进制,可以没有后缀。

实际操作:
1、在d:/oracle目录下建立archive1, archive2两个目录
2、修改init.ora文件,增加下面四行:
log_archive_start=true
log_archive_format=%t_%s.arc
log_archive_dest=d:/oracle/archive1
log_archive_duplex_dest=d:/oracle/archive2

3、进入svrmgrl
SVRMGR> connect internal/oracle
SVRMGR> shutdown immediate
SVRMGR> startup mount
SVRMGR> alter database archivelog;
SVRMGR> alter database open;

4、进入SQL*Plus
SQL> alter system switch logfile;

//检查d:/oracle/archive1及archive2目录下是否有归档的日志文件。

[*]在线启动或关闭归档方式
SQL> Alter system archive log start;
SQL> Alter system archive log stop;

三、数据库物理备份
[*]为了最大限度地进行恢复,应选择最合理的备份方法来防止介质失败导致的数据丢失。
(1)非归档的操作系统备份
(2)归档的操作系统备份
(3)Export工具备份
注释:
。用归档的操作系统备份的方法来恢复到介质失败后的失败点。
。用其它的恢复方法恢复到介质失败后的最后一次备份点。
。用Export工具创建一个直接的数据库备份文件,它不能与归档log文件组合使用。

1、完全数据库脱机备份:可以在归档及非归档两种模式下使用。
操作步骤:
(1)编写一个要备份的最新的文件列表。
(2)用SHUTDOWN命令关闭Oracle例程。
(3)用操作系统的备份工具,备份所有的数据文件、Redo Log文件、控制文件、参数文件。
(4)重启Oracle例程。

2、部分数据库联机备份:
备份步骤如下:
(1) 确认数据库运行在ARCHIVELOG下。
(2) 对于某一个表空间进行备份:
SQL> Alter tablespace 表空间名 begin backup;

(3) 操作系统备份相应数据文件

(4) 设置表空间备份结束标识:
SQL> Alter tablespace 表空间名 end backup;

恢复数据文件:
SVRMGR> Alter database RECOVER datafile '数据库文件名及路径';

<=等价=>

SVRMGR> RECOVER datafile '数据库文件名及路径';

3、部分数据库脱机备份:
备份步骤如下:
(1) 确认数据库运行在ARCHIVELOG下。
(2)将某一个表空间脱机:
SQL> Alter tablespace 表空间名 offline;

(3) 操作系统备份相应数据文件

(4) 将表空间联机:
SQL> Alter tablespace 表空间名 online;

恢复时也需要进行恢复数据文件:
SVRMGR> Alter database RECOVER datafile '数据库文件名及路径';

<=等价=>

SVRMGR> RECOVER datafile '数据库文件名及路径';

四、完全数据库恢复应用实例
[*]完全数据库恢复的语法:
  在数据库关闭时,数据库恢复语法(可以Mount):

SVRMGR> Alter database recover datafile 'filespec';
SVRMGR> Alter database recover database;
SVRMGR> Recover datafile 'filespec';
SVRMGR> recover database;

第1、3及第2、4条命令分别等价。

  在数据库运行时,数据库恢复语法(OPEN):
SVRMGR> recover tablespace 表空间名;
SVRMGR>recover datafile 'filespec';

1、数据库文件被删除,数据库关闭时,数据库恢复方法:
A、复制数据文件的备份文件
B、以mount方式启动数据库
C、恢复数据文件
SVRMGR> alter database recover datafile '数据文件名';
D、打开数据库
SVRMGR> alter database open;

2、数据库在运行时,数据文件被删除的数据库恢复方法:
A、将数据文件设置为offline:
SVRMGR> alter database datafile '数据文件名' offline;

B、复制数据文件的备份文件
C、恢复数据文件
SVRMGR> alter database recover datafile '数据文件名';

D、将数据文件设置为online:
SVRMGR> alter database datafile '数据文件名' online;

3、数据文件被删除,该数据文件没有备份,数据库恢复方法:
A、以mount方式启动数据库
B、运行以下命令:
SVRMGR> Alter database create datafile '被删除数据文件名及路径'
    as '被删除数据文件名及路径';

C、恢复数据文件
SVRMGR> alter database recover datafile '数据文件名';

D、打开数据库
SVRMGR> alter database open;

五、不完全数据库恢复实例:

1、恢复一个被Dropped的基表:
A、关闭数据库
B、拷贝全部的数据文件(不拷贝日志及控制文件)
注:这些拷贝的数据文件是以前做的数据文件的备份,现在拷贝回数据库数据文件所在目录,覆盖掉原来的。当然,最好在覆盖之前将现在的数据文件及归档日志做好备份。

C、实施基于时间的不完全数据库恢复
SVRMGR> Alter database recover database until time '2002-05-17:9:00:00';
D、打开数据库
SVRMGR> Alter database open RESETLOGS;
// 执行了resetlogs之后,文件同步号将从0开始,以前所有的归档日志全部失效。

2、恢复一个被Dropped的表空间:
A、查询跟踪文件,确定表空间删除时间
D:/oracle/admin/db_name/bdump/sidAlrt.log

B、关闭数据库,复制未删除表空间前的全部数据文件及控制文件,不复制日志文件。

C、实施基于时间的数据库恢复:
SVRMGR> Alter database recover database until time '2002-05-17:9:00:00' using backup controlfile;

D、打开数据库
SVRMGR> Alter database open RESETLOGS;

六、数据库逻辑备份:(Export/Import)

1、exp user01/user01 file=user01  // 用户方式:将user01用户的所有数据导出到user01.dmp文件中
2、exp user01/user01 file=user01_table tables=(emp,dept, pay, ...)   // 表方式,将指定用户的指定表导出。
3、exp    // 交互方式
4、卸出(导出)大表:
exp user/password file=filename direct=y  ...
// 加上direct=y,表明用直接路径卸出数据,不通过内存,直接卸出到磁盘,效率高,节省内存。

4、全部数据库卸出:
exp system/manager file=fulldb full=y direct=y

// 加上full=y,表示将整个数据库全部卸出。

用户方式和表方式可以在NT 与 UNIX之间的Oracle进行数据传输,但整个数据库方式不能,因为包含了相关的数据文件信息。

七、卸出表空间:
1、检验表空间自包含性:检查表空间是不是与其它表空间有外键约束,有外键约束的不能卸出。
SQL> execute ...

2、将表空间设为只读

3、使用export卸出表空间
exp transport_tablespace=y tablespaces=mis file=expdat.dmp

4、使用Import装入表空间
imp transport_tablespace=y datafile='d:/oracle/oradata/x.dbf' tablespaces=mis file=expdat.dmp

八、Windows 计划任务备份数据文件
1、C:/> net start schedule //启动计划服务
    net stop schedule //停止计划服务
   
2、AT命令安排计划:
C:/>at 22:00 /every:m,t,w,th, f, s, su d:/fullback.bat // 每周一到周日的晚上十点运行d:/fullback.bat批处理文件

C:/>at /delete /yes  // 删除全部计划

3、fullback.bat
svrmgrl @d:/fullback.sql

4、fullback.sql
connect internal/oracle
shutdown immediate
host copy d:/oracle/oradata/ora8i/*.* e:/back
startup

还可以为数据库在线备份建立脚本通过AT调用执行,实现数据库的联机备份。

[第八章 Oracle 数据库的优化与调整]

一、下面三个参数属于SGA区的设置,主要看服务器内存是不是需要扩充。

1、数据缓冲区计算:(DB_BLOCK_BUFFERS)

SQL> select 1 - (phy.value /(blk.value+con.value))
 "   Hit Ratio"
 from v$sysstat phy, v$sysstat blk, v$sysstat con
 where phy.name = 'physical reads' and
   blk.name = 'db block gets' and
   con.name = 'consistent gets'
  
Hit Ratio最好是大于90%,需要在数据库在最繁忙的时候的命中率,否则需要增加内存。

2、日志缓冲区计算(log_buffer)
v$latch

sum(misses) 越接近于零越好。

3、共享池大小计算(shared_pool_size)
(1) v$librarycach:  PINS(命中),Reloads(失败)

Reloads/(pins + reloads) * 100 -> 失败率 -> 应小于1%,否则需要扩内存。

(2) v$rowcache: GETS(取到),  GETMISSES(失败)

二、排序区参数计算(SORT_AREA_SIZE):v$sysstat

sorts(disk) / sorts(memory)+sorts(disk)  失败率 < 10%

三、磁盘存储参数测算:
计算以下存储参数:
initial
next
minextents
maxextents
pctincrease

如果使用本地化管理,不需要计算以上参数。

四、数据库参数自动统计计算
1、修改参数文件:timed_statistics=true,重启数据库

2、在数据库最繁忙的时段运行下面两个SQL程序(在Oracle目录中搜索这两个文件)

SVRMGR>@d:/oracle/ora81/rdbms/admin/utlbstat.sql   
SVRMGR>@d:/oracle/ora81/rdbms/admin/utlestat.sql

3、查询d:/report.txt来看统计结果。

五、回退段优化设计
1、对于大事务,设计大回退段,提高数据操作速度。

步骤如下:
A、创建一个专用的回退段表空间。例如:rb100
B、在回退段表空间rbs100上创建大的回退段。
SQL> create rollback segment rbs100
 tablespace rbs100
 storage(initial 50m);
C、使回退段表空间online
SQL> Alter rollback segment rbs100 online;

D、指定用户使用专用的回退段表空间:
SQL> set transaction use rollback segment rbs100;  // 必须在事务开始前指定

E、事务结束后,删除回退段及表空间。

教师操作实例:
System用户操作:
SQL> create tablespace rbs1 datafile 'd:/oracle/oradata/ora8i/rbs1_01.dbf' size 10m

SQL> create rollback segment rbs100 tablespace rbs1;

SQL> alter rollback segment rbs100 online;

SCOTT用户操作:
CREATE table bb(s1 char(20));

insert into bb values('abcdefghi');

commit;   // 必须在事务开始之前设置回退段

set transaction use rollback segment rbs100;

system用户操作:

alter rollback segment rbs100 offline;

drop rollback segment rbs100

drop tablespace rbs1;

2、回退段I/O调整,具体步骤:
A、创建多个回退段表空间,对就不同物理磁盘,以平衡磁盘I/O
B、在多个表空间上分别创建回退段。例如:
rbs1:rbs01, rbs02, rbs03, rbs04, rbs05
rbs2: rbs06, rbs07, rbs08, rbs09, rbs10

C、修改参数文件,使回退段交叉排放。例如:
rollback_segments=(rbs01,rbs06,rbs02,rbs07,rbs03,rbs08,...)

[Oracle Developer/2000 系统开发工具]

简介:
Form: 开发基于Form应用系统,是Developer/2000的主要开发工具。
Report: 报表开发工具,开发设计各种报表。
Graphics:图形设计工具,开发基于数据库的图形界面

Form 包括以下三个工具:
。Form Builder 设计与开发组件
。Form compiler 编译组件
。Form Runtime 运行组件

[Form Builder 设计]

一、创建一个简单的Form应用

表在Form Builder中称为数据块。

在新建的Form中的表格字段中可以输入查询条件,按F8按条件查询。


外,可以在字段中输入变量,例如:在emp表中的sal(工资)字段输入变量:x,在执行查询时,输入:x> 2000 and :x <
3000,则表示查询工资在2000及3000之间的人员。如果要查询1981年的人员,则在date字段输入:x,条件为:To_Char(:x,
'yyyy) = '1981'

查询最大工资::x = (select max(sal) from emp)

二、创建主从型Form应用:
1、使用主表创建主块
2、使用子表创建子块
3、建立主表与子表之间的关联

三、布局设计(Layout)

四、域属性表(Properties): 双击某字段即可调出属性表

格式掩码

五、创建文本项(Text Item):

文本项:用于显示数据库的统计结果

名称
数据类型
格式掩码
计算模式
汇总函数:总和
数据块:emp
数据项:fullsal

公式:水平计算
汇总:垂直计算

工资及奖金合计::sal + nvl(:comm,0)

数据->用项同步化

记录->显示的项数:0 -> 1

六、创建值列表Lov(List of Value):

七、创建按钮(Push Button):

1、创建文本类型按钮:
数据查询,条件查询,工资总和,报表打印、退出系统
2、创建图标类型按钮:
(1)常用缺省图标:
save:数据提交
rt_rdel:数据删除
rt_radd: 数据插入
rt_rec4: >>
rt_rec3: >
rt_rec2: <
rt_rec1: <<

(2)更改按钮属性
图标化:是
图标文件名:<Icon File path>
鼠标导航:否
显示的项数:1

(3) 增加按钮提示
保存
删除
插入数据
第一条记录
下一条记录
上一条记录
最后一条记录

八、创建显示项(Display Item):
显示项:只读数据项,用于显示数据库的统计结果。

九、创建单选按钮(Radio Button):

(1) 增加了单选按钮后,先到“对象导航器”中修改“Radio Group”的属性

名称:
鼠标导航:否
数据类型:数值
初始值:10

财务部(10)、销售部(20)、开发部(30)、网络中心(40)

示// 数据->需要:如果选择“是”,则表明数据为非空,不允许为空,如果不在表中输入查询条件,则不允许移动光标焦点,应选“否”。

十、复选框(Check Box)

增加一个复选框,修改其属性:
名称:
标签文本:
复选时的值:y
未复选时的值:n
鼠标导航:否
显示的项数:1
数据库项:否

[Trigger 触发器设计]
一、按钮触发器设计:
触发器类型:WEHN-BUTTON-PRESSED
触发器代码:使用PL/SQL及函数编写程序代码。

Execute_Query;   // 执行查询的函数,这是写在相应按钮上的PL/SQL执行语句的脚本

编译,关闭,执行。

Enter_Query; // 条件查询函数

Exit_Form; // 退出系统函数

常用的对于数据库操作的函数:
Create_Record;  // 数据插入
Delete_Record;  // 数据删除
Commit_Form;  // 数据提交
Execute_Query;  // 无条件数据查询
Enter_Query;  // 条件查询
Next_Record;  // 下一条记录
Previous_Record;  // 上一条记录
First_Record;  // 第一条记录
Last_Record;  // 最后一条记录
Scroll_Up;  // 上滚一屏
Scroll_Down;  // 下滚一屏
Exit_Form;  // 退出系统

这些函数名不区分大小写。

如果在执行查询时提示Oracle错误,不能查询,有可能就是因为Form中一个与数据库字段无关的对象的“数据库项”设置成了“是”,将其改成“否”即可。

工资总和按钮的WHEN-BUTTON-Pressed的pl/sql脚本:select sum(sal) into :Display_sumsal from emp;

二、创建Form级触发器完成数据库的自动查询与统计:
A. 在Form启动时,进行自动查询

触发器名称:WHEN-NEW-FROM-INSTANCE
对象导航器->表格->Form1->触发器->新增

脚本内容:Execute_Query;

B. 在Form启动时,进行自动统计计算

触发器名称:POST-QUERY
对象导航器->表格->Form1->触发器->新增
select sum(sal) into :Display_sumsal from emp;

C. 显示动态时间:
触发器名称:POST-QUERY
自动显示统计时间:yyyy年mm月DD日
增加一个显示项:DISPLAYTIME
数据类型:字符
立体:无

修改POST-QUERYR的脚本,增加一行:
:DISPLAYTIME := To_Char(sysdate, 'yyyy"年"mm"月"dd"日"');  --// 显示的是客户端时间

select To_Char(sysdate, 'yyyy"年"mm"月"dd"日"') into :DISPLAYTIME from dual; --// 显示的是服务器端时间

[C*]在编辑触发器脚本中汉字不能正确显示的解决办法:
先退出FormBuilder。然后:
regedit -> HKLM-> Software -> Oracle -> 新建字串de20_plain_edit,键值为1。
再重新进入FormBuilder即可解决所有的汉字显示问题。

D. Form启动时,MDI窗口最大化及标题设置,同样在FORM的POST-QUERY触发器中设置:
SET_Window_Property(FORMS_MDI_WINDOW, WINDOW_STATE, maximize);
Set_Window_property(FORMS_MDI_WINDOW, TITLE, '公司员工工资情况一览表');

设置MDI子窗口Window1:
SET_Window_Property('window1', WINDOW_STATE, maximize);
Set_Window_property('window1', TITLE, '员工管理信息系统 Version 200205 Build 1');

[*] 进入Form1模块的属性设置-> 菜单模块 -> default&smartbar ,default表示菜单,smartbar表示工具栏,去掉就表示没有这些东西。

[*] Window1属性-> 模式 -> 是。意味着这是mdi窗口中的最后一个窗口。还可以取消最大最小化等按钮,实现mdi子窗口看上去与主窗口好象一个窗口。

三、单选按钮触发器:
触发器类型:WHEN-RADIO-CHANGED
脚本:
Declare
 string varchar2(50);
 v_dname dept.dname%type;
Begin
 select sum(sal), count(*) into :Display_item2, :Display_item3 from emp
  where deptno=:select_deptno;
 select dname into v_dname from dept where deptno = :select_deptno;
 string := v_dname || '部门统计结果';
 Message(string);

Exception
 when NO_DATA_FOUND THEN
  Message('数据库中没有编码为'||:select_deptno||'的部门。');
End;

四、时间触发器(Timer):
1、创建计时器,确定时间间隔:
触发器名称:WHEN-NEW-FORM-INSTANCE
增加脚本:
Declare
 timer_id timer;
Begin
 timer_id := Create_Timer('T1', 1000, REPEAT);
End;
-- T1:计时器名称(大写);1000:时间间隔(毫秒);REPEAT:重复

2、创建时间触发器的执行操作:
触发器名称:WHEN-TIMER-EXPIRED
Declare
 t_name varchar2(30);
Begin
 t_name := Get_Application_Property(TIMER_NAME);
 if t_name = 'T1' then Begin
  --显示Server时间
    select To_Char(Sysdate,'yyyy"年"mm"月"dd"日"hh24"时"mi"分"ss"秒"')
     into :DisplayTime from dual;
     --显示本机时间
   :DisplayTime :=To_Char(Sysdate,'yyyy"年"mm"月"dd"日"hh24"时"mi"分"ss"秒"') ;

--select To_Char(sysdate, 'yyyy"年"mm"月"dd"日"hh24"时"mi"分"ss"秒") into :DisplayTime from dual;
  End;
 End if;
End;

五、复选按钮触发器:
触发器类型:WHEN-CHECKBOX-CHANGED
脚本:
Begin
 if :ifprint='y' then
  Set_Item_Property('print_report', ENABLED, PROPERTY_TRUE);  --// 使打印按钮生效
 ELSE
  Set_Item_Property('print_report', ENABLED, PROPERTY_FALSE);  --// 使打印按钮无效
 end if;
end;

六、菜单设计

c:/orawin95目录下查找menudef.mmb,然后打开该文件,双击MENUDEF编辑原来的菜单(删除不要的,添加需要的),然后另存为自
己的菜单menu1.mmb,然后编译(文件->管理->编译文件CTRL+T)。。然后在Form1的属性设置中,将菜单模块直接设置成菜单文件的名称
及路径,例如:e:/xyf/menu1

七、基于数据库的图象字段存储:
1、在数据库中创建一个含有图象字段的基表。
SQL>Create table employee as select * from emp;
SQL> alter table employee add(photo long raw);  --//加上long raw字段后,该表就不能再用select * 去查询

2、对图象文件进行唯一性编码

SQL> Spool e:/empno
SQL> select empno from emp;
SQL> Spool off;

生成e:/empno.lst文件,存储了所有雇员的empno列表作为图象文件的唯一性编码
如:7788.jpg...

3、创建Form,编写触发器调用图象文件:photo.fmb
photo属性->大小风格 -> 调整

empno字段的触发器:WHEN-NEW-ITEM-INSTANCE
Declare
 photo_name varchar2(50);
Begin
 photo_name := 'e:/xyf/'||To_Char(:empno)||'.jpg';
 Read_Image_File(photo_name, 'jpg', 'photo');
End;

4、图象数据提交数据库。

5、删除本机图象,删除触发器。

八、标签画布(Page):
不使用数据块向导,直接在“表格”处新增一个Form,然后进入布局编辑器,选择左边工具栏中的“标签画布”新建一个标签画布。然后回到对象导航器,删除原来的画布。

在布局编辑器中,在标签位置按鼠标右键->属性选项板,可以进入标签画布的根的属性设置中,而在某个标签的中间部位按鼠标右键->属性选项板,则可以进入这个标签页的属性设置。

对象(导航器) -> 数据块 -> 关系 -> 新建:dept.deptno = employee.deptno

各个标签页的显示顺序,由在各个页上的数据块在对象导航器中的排列先后顺序确定,可以通过鼠标拖动来直接调整其排列顺序。

[Oracle Application Server应用服务器]
试验环境:
Oracle Server:
IP: 75.64.23.30
SID: orcl

Oracle Application Server:
IP: 75.64.23.40
Host Name: ntsvr1

用户:
user01/user01, ... user40/user40

一、WWW原理简介

URL: Uniform Resource Locator
HTTP: Hyper Text Transfrer Protocol
HTML: Hyper Text Markup Language

二、Oracle Application Server概述

三、Oracle Application Server 服务器启动
在操作系统下命令启动:
$ owsctl start   // 启动OAS服务器
$ owsctl start -nodemgr // 启动OAS管理节点

管理节点:
IP: 75.64.23.40:8888  //管理节点的端口号为8888
管理员用户:Admin

四、Oracle Application Server 原理简介
http://www.oracle.com:80/news.html     // 静态页面
http://www.oracle.com:121/cgi/plsql/p_query.go  // 动态页面

五、Oracle Application Server 配置步骤:
1、加载PL/SQL 程序包(通过IE登录到OAS的远程管理节点):

http://ntsvr1:8888/  (配置方法:在c:/windows目录下建立文本文件hosts,内容为:75.64.23.40 ntsvr1)

OAS实用程序-> 安装 -> PL/SQL工具包 -> 数据库连接串 -> sys用户口令 -> 应用。

如果OAS与Oracle服务器在一台机器上,则使用Oracle_SID,否则要使用连接串。

2、创建HTTP监听进程
在创建HTTP监听进程时,需要确定的信息:
监听进程的名称
端口号:(1 - 16653 之间)
主机名称:

3、创建DAD(Data Access Description)数据存取描述器,建立OAS与数据库之间的连接
Oracle Application Server => DB存取描述

需要确定的信息:
。名称:
。合法的数据库用户名及口令
。数据库位置:
。网络连接串名

4、创建应用:

选择应用程序所使用的语言:PL/SQL
应用程序名:mis01

应用的状态标志一般为红旗,没有关系。

5、创建插件。确定信息如下:
。插件名称:mis01
。显示名称: 人员工资信息
。虚拟路径:/cgi/plsql  //这里怎么设置,用户在输入时就要怎样输入URL
。物理路径: %ORAWEB_HOME%/bin
。所连接的数据库信息:通过DAD确定(下拉菜单选择)

用户输入URL范例:http://75.64.23.40:1234/cgi/plsql/p_test

[***]所有配置结束后,重新加载OAS。

六、使用PL/SQL开始Web页面

1、标记函数:
htp.htmlOpen   <HTML>
htp.htmlClose </HTML>
htp.headOpen <HEAD>
htp.headClose </HEAD>
htp.bodyOpen    <BODY>
htp.bodyClose   </BODY>
htp.comment      <!--    -->

2、PL/SQL过程、函数、包:
owa_cookie
owa_image
owa_util
owa_opt_lock
owa_pattern
owa_sec
owa_text

3、
HTML:
<html>
<head>
<title>欢迎使用Oracle Application Server</title>
</head>
<body><p>
<strong>欢迎使用Oracle Application Server!</strong></p>
</body>
</html>

对应的PL/SQL程序:
Create or Replace Procedure P_ShowExample  AS
       BEGIN
         htp.htmlopen;
         htp.headopen;
         htp.title('Oracle Application Server 4.0!');
         htp.headclose;
         htp.bodyopen;
         htp.strong('欢迎使用Oracle Application Server!');
         htp.bodyclose;
         htp.htmlclose;
       END;

在SQL*Plus中运行上面的程序创建相应的存储过程。

4、显示数据库中基表的数据:P_TEST.sql
Create or Replace Procedure P_Test  AS
           ignore boolean;
              BEGIN
                     htp.htmlopen;
                     htp.headopen;
             --      htp.title('Display the Current Users in Oracle Database!');
                     htp.headclose;
                     htp.bodyopen;
                     htp.header(1, '  输出数据库基表中数据');
                     ignore := owa_util.tableprint('emp','BORDER',owa_util.html_table);
                     htp.bodyclose;
                     htp.htmlclose;
              END;
             
5、动态数据基表名称:P_query.sql
运行方法:http://75.64.23.40:1234/cgi/plsql/p_query.go

6、webalchy.exe: //可以将标准的html文件转换成PL/SQL程序。

7、使用列表项,选择部门编码:P_Select.sql
http://75.64.23.40:1234/cgi/plsql/p_select.go

[C*] owa_util.TablePrint函数用法
owa_util.tablePrint(c1,c2,c3,c4,c5,c6,c7,c8)

其中:
c1: 表名。例如:'emp'
c2: 是否有表格线。'BORDER'
C3: 表格的格式。owa_util.html_table
c4: 基表中的列名。缺省为'*',即所有列
c5: where语句:例如:'where deptno = '||v_deptno||' or sal > '||v_sal|| 'order by sal',
c6: 列名的别名
c7: 最少显示多少行,0(全部显示)
c8: 最大显示多少行,缺省为NULL。

8、输入员工编码,显示员工信息:P_empno.sql

9、多个选择项:列表项及文本框输入:P_Mselect.sql

10、使用无线组(Radio Group) 显示部门信息:P_rselect.sql

11、向数据库中录入员工信息:P_input.sql

[Report Builder 报表设计]
一、创建一个简单的报表:
Report Builder -> 工具 -> 报表编辑器 -> 新建查询

然后布局向导创建布局。

预览界面->点左上角图标 -> 数据模型 -> 再点左上角图标 -> 预览界面

二、创建分组报表
在数据模型界面拖动要分组的列到列外即可创建分组。

1、增加公式列(水平方向计算):
数据模型->左边工具栏中公式计算图标。
return :sal + nvl(:comm,0);

2、增加汇总列(垂直方向计算):

每次有新列(域)增加后,都要在数据模型主窗口->鼠标右键->报表向导中进行适当的修改。

三、布局设计(Layout)
1、报表向导->标签:修改标签为中文

2、视图->布局模型
编辑->选择全部
左边工具栏->添充颜色,格式->字体

页边距:相当于页眉,顶部工具栏中按钮。

在增加文本框时,如果默认字体不是中文,请先在格式->字体中设置为中文字体,然后再输入。

双击域可以设置字段属性。

四、创建主从型报表:使用主从型 藏青创建主从型报表

1、在对象导航器->报表->新建->手动,进入数据模型窗口。

2、SQL:
(1)select * from dept
(2) select * from emp

(3)点击左边纵向工具栏中“数据链接”:从dept.deptno 拖动到emp.deptno1放开,建立数据链接。

(4)报表向导
 。风格:上边分组。
 。组:两个组均是纵向
 。域:除了重复的deptno1之外都要
 。模板:无模板。

3、在布局模型中调整表格结构

五、创建矩阵报表:
1、构造矩阵报表至少需要四个组:
一个横向显示数据的组
一个纵向显示数据的组
一个在交叉点显示数据的组
一个矩阵单元组

2、操作步骤:

(1)手动创建一个报表。

(2) SQL1:select deptno, job, sum(sal) from emp group by deptno,job;

(3) 将deptno和job拖出成为两个分组的条件。

(4) 点击左方工具栏交叉单元按钮,将G_2.DEPTNO 与 G_3.job括起来,这样成为一个G_4交叉组。

(5) 报表向导
风格:矩阵
单元:sum_sal
总计:总和(sum_sal)
模板:无

(6) 布局模型重新布局。

六、分组矩阵报表:

(1)手动创建一个报表。

(2) SQL1:select To_Char(hiredate, 'yyyy') year, deptno, job, sum(sal) from emp group by To_Char(hiredate,'yyyy'), deptno, job;

Q_emp, G1

(3) 将Year,deptno和job拖出成为三个分组的条件。G_year, G_deptno, G_sulsal, G_job, G_cross

(4) 点击左方工具栏交叉单元按钮,将G_3.DEPTNO 与 G_4.job括起来,这样成为一个G_5交叉组。

(5) 报表向导
风格:分组矩阵

[Graphics Builder 图表设计]
一、创建饼图(Pie):
1、打开Graphics Builder,连接数据库。
菜单:图表->创建图表

2、输入SQL语句确定数据源:select deptno, sum(sal) from emp group by deptno; -> 执行 ->确定

3、图表:饼图,名称:Pie

4、菜单:图表->框架->饼框架->显示数据值,显示百分比值

可以修改所显示数据值的字体、颜色等。可以修改饼图的框架、侧面及阴影的填充颜色等。

二、创建列图(Column):

1. SQL: select ename, sal from emp

2. 名称:column

图表框架: 深度尺寸,阴影尺寸,阴影方向。显示绘图框架(选中),显示图例(去掉)。

侧面、顶部、阴影的填充颜色,不要修改正面的填充颜色。

双击两个坐标轴可以设置坐标轴属性,去掉“显示坐标轴标签”

3. 画一个矩形将图表括起来,填充颜色然后置后,给图表加上标题。

三、创建主从型图表(Drill-Down):
1、创建主图:pie
select deptno, sum(sal) from emp group by deptno

2、创建参数
导航器-> 参数 -> 新增
名称:n
类型:数字
初始值: 10
3、使用参数创建子图
新建图表-> 新建查询 -> select ename, sal from emp where deptno=:n; // 将参数n放入第二个查询中。
子图名:column

4、建立两个图表之间的关系
选饼图中心双击->对象属性->细化:
设置参数:N
对于值:DEPTNO
执行查询:query1(新建的子查询)

5、运行

四、图表切割:
选饼图中心双击->对象属性

过程->编辑

rrow number;

chart og_object;

BEGIN
 chart := Og_Get_Object('pie'); // 将名为pie的图表放到chart变量中。
 rrow := Og_Get_Row(HITOBJ);
 Og_Set_Explosion(chart, rrow, 'deptno', 50);  // 切割的距离为50个小数点
 Og_update_Chart(Chart, OG_ALL_CHUPDA);
End;

[Developer/2000集成]
一、Form调用Report:
1、创建一个含有参数的报表:r11
2、在Form中调用Report:(Form以前面建立的Form1 (Form3)为例)。

报表打印按钮的WHEN-BUTTON-PRESSED脚本:
Declare
 pl_id paramlist;
Begin
 pl_id := Create_Parameter_List('tmpdata');
 Add_Parameter(pl_id, 'dno', TEXT_PARAMETER, To_Char(:deptno));
 Add_Parameter(pl_id,'paramform',TEXT_PARAMETER,'no');
   Run_Product(REPORTS,'e:/xyf/r11.rdf',
    ASYNCHRONOUS,RUNTIME,FILESYSTEM,pl_id,null);
   Destroy_Parameter_List(pl_id);
End;

二、Form 调用Graphics:
1、创建一个含有参数的图表
select ename, sal from emp where deptno = :dpt;

2、在Form中创建图表项
3、编写触发器调用图表

访问表空间权限控制:
去掉用户对某个表空间的访问权限
ALTER USER ZYIBSS QUOTA 0 ON IBMS_DATA_DATA;
ALTER USER ZYIBSS QUOTA 0 ON IBMS_DATA_IDX;

增加用户对某个表空间的访问权限
ALTER USER ZYIBSS QUOTA UNLIMITED ON IBMS_DF_DATA;

移动表空间:
alter table tcm-user move tablespace  ibms-data-data

append是优化提示器,这个最好不用,你可以用并行提供来做
insert /*+parallel(emp,2) */ into emp nologging 2是代表什么啊?
2是用2个CPU来并发做事
这个有什么好处,可以加快速度?还是 ?

能允分利用多处理器的好处喽
会明显变快的
看你的主机是多少CPU的了,我最多用16
反正690有12个cpu
也可以使用索引提示
 怎么用??
如果用到某个table的索引
 /*+ index(字段名) */
 提前告诉优化器要用到的索引是吗?
/*+ index(table名,字段名)*?
 是的,有时你现成的索引,oracle不一定会用,指定后oracle尽量用你指定的索引
还有什么好东西啊?大哥啊。给我点资料有不咯?呵呵
 /*+ index(table名,字段名)*/这个是放在select语句里吗 ??放在什么位置啊
 放在第一个关健字后梑
 我用了/*+parallel(emp,2) */还要用 NOLOGGING吗??
也可以用
 爽,谢谢。不过很抱歉。今天因为我多加了个/*+append*/使的tcm-cust-rela增大了100多倍,造成表空间不够,所以数据还没有出来,我刚才才通过测试找出来。
 优化器多时oracle会根据实际情况选择一个来用
 INSERT /*+parallel(TCM_CUST,2) */ INTO TCM_CUST NOLOGGING (字段)values(值) 这种写法对不?
关于这方面的书,我明天找一下,如果有我发给你,我手头上有一本事,但讲的很少。
 好。我现在给你们准备数据。郁闷啊。浪费了一天的时间。
  这样很快的
 690一共12个cpu ,我填10个会不会有问题啊?
 晚上别熬的太晚了
 没事,oracle有大量的并发能力,关健要看数据有没有把值设的大一点,现在业务少,可以这么做

select * from (select rownum as aa, a.* from tcm_user a where rownum<100) where aa>10

关于Oracle中的时间计算问题!
--------------------------------------------------------------------------------
  to_date('2003-8-1 18:20', 'yyyy-mm-dd HH24:MI') - to_date('2003-7-3 18:35', 'yyyy-mm-dd HH24:MI')
   得到一个值,如何将得到的值转化为分钟?也就是说它们两个值之间相差的分钟?
--------------------------------------------------------------------------------

(to_date('2003-8-1 18:20', 'yyyy-mm-dd HH24:MI') - to_date('2003-7-3 18:35', 'yyyy-mm-dd HH24:MI'))*24*60

(dateA-dateB)*1440 = N 分
(dateA-dateB)*86400 = N 秒

round()四舍五入
  ceil()大于n的最小整数

如果不小心把表给delete掉了并且commit了,不要紧,你可以用如下语句进行恢复
 select * from tfm_action_list as of timestamp (systimestamp -interval'4000'second)

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=419368

zhuanzi:blog.csdn.net/jxnucsb2008/article/details/557827

上一篇:深入理解docker的link机制


下一篇:小程序开发基础-swiper 滑块视图容器