ITPub博客

首页 > Linux操作系统 > Linux操作系统 > oracle的使用心得

oracle的使用心得

原创 Linux操作系统 作者:silRiver 时间:2009-06-09 16:58:05 0 删除 编辑

1、DDL(Data Definition Language) Command
   create,alter,drop objects;
   grant,revoke privileges and roles;
   establishing auditing options;
   add comments to the data dictionary;
   Before and after each DDL statement,Oracle implicitly commit the current transactions.

2、DML(Data Manipulation Language) Command
   Query and Modify data within existing schema objects;
   DML statements consist of DELETE,INSERT,SELECT and UPDATE statements;
                        EXPLAIN PLAN statements;
                        LOCK TABLE statements;
   Unlike DDL Command , a commit is not implicit , after execute DDL Command ,must execute commit command    to commit a transaction;

3、Dynamic Performance Tables
   These tables are created at the instance startup and used to store information about the performance    of the instance. This information includes connection informatioion,I/OS, initialization parameter    values and so on..

4、Procedure and Function are identical except that Founction are always return a value(Procedure do not).

5、Schema is a collection of Objects that associated with the DataBase.

6、SGA is made up of :
   DataBase Buffers;
   Redo Log Buffers;
   The Shared Pool;

7、Transaction is a logical unit of work consisting of one or more SQL statements,ending in a commit or rollback.

8、 The DataBase
The Physical Layer
(1)One or more datafiles;
(2)Two or more redo log files;
(3)One or more control files;
The Logical Layer
(1)One or more tablespaces;
(2)The database schema;

9、The database is devided into one or more logical pieces known as tablespace;

10、Recommend that every one need DBA roles should have a different account , thus , if auditing is enabled , there is a record who made these system changes.

11、The Instance is the logical term that refers to the components necessary to access the data in a database.

12、数据库实例(也称为服务器Server),是用来访问一个数据库文件集的一个存储结构及后台进程的集合。Oralce并行服务器是指一个单独的数据库可以被多个实例访问。

13、查询实例名:
   select instance_name from v$instance;

14、查询动态视图v$waitstat、v$system_event、v$session_event、v$session_wait和v$ buffer_pool_statistics(在Oracle8中通过catperf.sql脚本创建)以获取下面所的统计信息,
目的是为了检查服务器进程是否正等待DBWR(对单个会话而言,也对整个数据库而言)。

15、
(1)SMON:系统监控程序
(2)PMON:进程监控程序
(3)DBWR:数据库写入程序
(4)LGWR:日志写入程序
(5)CKPT:检查点进程
(6)ARCH:归档日志
(7)RECO:恢复进程
(8)SNPn:快照进程
(9)LCKn:锁定进程
(10)Dnnn:调度程序进程
(11)Snnn:服务器进程
(12)Pnnn:并行查询服务器进程

16、数据库备份之前,若使用了shutdown abort命令,则需要进行如下操作,然后才能进行数据库备份:
1)    执行一个shutdown abort命令;
2)    启动数据库实例;
3)    执行shutdown命令;

17、使用OPS数据库时,如何解决两个服务器同时对同一记录的更新?
更新同一个表的数据的用户使用同一个实例来访问数据库。

18、通过ORACLE数据库对非ORACLE数据库进行访问,首先需要在运行非ORACLE数据库的服务器端安装ORACLE透明网关产品,每种被访问的数据引擎需要一个独立的网关;然后需要在本地ORACLE数据库中建立一个数据库连接(DATABASE LINK)。

19、外部文件访问:
1)    用作脚本文件的源代码写入SQL*PLUS、SQL、PL/SQL中;
2)    用作SQL*PLUS脚本文件的输出,用SPOOL命令生成;
3)    用作PL/SQL程序的输入或输出,通过UTL_FILE软件包访问;
4)    用作PL/SQL程序的脚本文件的输出,通过DBMS_OUTPUT软件包生成;
5)    用作通过BFILE数据类型在数据库中引用的外部数据,BFILE数据类型含有一个指向外部二进制数据文件的指针,用户必须通过CREATE DIRECTORY命令,在ORACLE中创建一个目录指针,指向存储文件的目录。
6)    用作通过DBMS_PIPE访问的外部程序,该程序必须以ORACLE支持的3GL来编写。

20、取消用户在SYSTEM表空间上创建对象的定额:
ALTER USER USER_NAME QUOTA 0 ON SYSTEM;
注:
如果一个用户被授权UNLIMITED_TABLESPACE系统权限或RESOURCE角色(Resouce角色拥有使用数据库中所有表空间的权限),则这个授权将覆盖用户的任何定额设置。
21、创建一个用户,并且指定缺省表空间:
CREATE USER USER_NAME IDENTIFIED BY USER_PASSWORD DEFAULT TABLESPACE TABLESPACE_NAME;

22、重新指定用户的缺省表空间:
ALTER USER USER_NAME DEFAULT TABLESPACE TABLESPACE_NAME;

23、从数据表中分离出已有的索引:
ALTER INDEX INDEX_NAME REBUILD
   TABLESPACE INDEX_TABLESPACE
   STORAGE(INITIAL 2M NEXT 2M PCTINCREASE 0);

24、创建表时指定数据表空间和索引表空间:
CREATE TABLE TAB_NAME(
COLUMN_A TYPE,
COLUMN_B TYPE,

COLUM_N TYPE,
CONSTRAINT TAB_NAME_PK PRIMARY KEY (COLUMN_A)
USING INDEX TABLESPACE TABLESPACE_INDEXES
STORAGE(INITIAL 2M NEXT 2M PCTINCREASE 0))
TABLESPACE TABLESPACE_DATA
STORAGE(INITIAL 5M NEXT 5M PCTINCREASE 0);

25、TEMP表空间只有在大型排序操作时才使用;

26、STORAGE子句的意义:
Storage(initial 盘区大小 next 盘区大小 pctincrease 每个顺序盘区几何增长的系数);
使用非零pctincrease参数的结果:
storage(initial 10M next 10M pctincrease 50);
盘区号        大小        总块数        盘区容量注释
1            10            10            INITIAL
2            10            20            NEXT
3            15            35            NEXT×1.5
4            22.5            57.5            NEXT×1.5×1.5
5            33.75        91.25        NEXT×1.5×1.5×1.5
.. .. .. .. .. ..
理想的情况:
一个段只具有一个大小合适的盘区,并且next值较小,设表的pctincrease值为零;
实际上:
在表空间级设置pctincrease的值为零,会影响ORACLE自动合并表空间中自由空间的能力,把表空间缺省pctincrese设置为一个非常低的值,例如1;

27、通常称作TEMP的临时表空间,由于其自身的特点会有很多碎片,临时段总是在不断的创建、扩展和撤销,对于临时表,将INITIAL和NEXT盘区大小设为表空间大小的1/20到1/50,对于这个表空间,INITIAL和NEXT缺省设置应该相等,PCTINCREASE的值为0,这样,段将有同样大小的盘区构成,当撤消这些段时,下一个临时段将能够重新利用这些已撤消的盘区。

28、
1)将一个表空间改为临时表空间:
alter tablespace tablespace_name temporary;
2)将一个表空间转换为能存储永久对象:
alter tablespace tablespace_name permenent;
3)强制表空间合并其自由空间(只能合并位置相邻的自由盘区):
alter tablespace talbespace_name coalesce;

29、
1)手工缩放数据文件(只能增大不能减小):
alter database datafile '$path/datafile01.dat' resize nnnM;
2)创建一个在需要时自动扩展的文件:
CREATE TABLESPACE DATA
DATAFILE '$PATH/DATAFILE01.DAT' SIZE 200M
AUTOEXTEND ON
NEXT 10M
MAXSIZE 250M;
3)通过ALTER TABLESPACE增加一个新的数据文件:
alter tablespace tablespace_name
add datafile '$path/datafile02.dat' size 200M
autoextend on
maxsize 300M;

40、移动数据文件:
1)    关闭实例;
2)    使用操作系统命令来移动数据文件;
3)    安装数据文件并使用ALTER DATABASE命令改变数据库中的文件名;
4)    启动实例;
具体步骤如下:
1)>svrmgrl
>connect internal
>shutdown
>exit
2)mv /db01/oracle/cc1/data01.dbf /db02/oracle/cc1/
3)>svrmgrl
>connect internal
>startup mount cc1
>alter database rename file '/db01/oracle/cc1/data01.dbf' to '/db02/oracle/cc1/data01.dbf';
4)    startup

31、
查看回滚段名称:v$rollname
查看表空间:dba_tablespace;
查看用户表空间:user_tablespaces;
查看回滚段状态信息:dba_rollback_segs;
查看数据库回滚段的当前分配情况:dba_segments;

32、
若系统中有多个表空间,就需要在system表空间中创建"第二回滚段"来支持多个表空间,有了"第二回滚段",system表空间就只用于管理数据库级的事务。

33、
ipcs | grep oracle
ipcrm [-m|-s] ipcid(数字)

34、连接字符串:||   
select 'drop talbe '||table_name from user_tables;

35、视图中不能使用order by,但可以用group by 代替来达到排序目的:
create view as select b1,b2 from table_b group by b1,b2;

36、用户间复制数据:
copy from user1@databasex to user2@databasey create table2 using select * from talbe1;

37、察看数据库的大小,和空间使用情况
select b.file_id FileID,b.tablespace_name TableSpace,b.file_name PhysicalFileName,b.bytes TotalBytes,(b.bytes-sum(nvl(a.bytes,0))) UsedSpace,sum(nvl(a.bytes,0)) FreeSpace,sum(nvl(a.bytes,0))/(b.bytes)*100 FreePecent from dba_free_space a,dba_data_files b where a.file_id=b.file_id group by b.tablespace_name,b.file_name,b.file_id,b.bytes order by b.tablespace_name;

38、Oracle提供了几个包,它们可以用来完成很多任务,从内部进程通信到文件I/O,到在PL/SQL块中动态创建和执行SQL语句。所有这些包由SYS用户所拥有-当Oracle最初安装时两个用户中的一个,这些包中最重要的包括:
DBMS_ALERT          不用轮询就允许应用命名并发出警告条件信号的过程与函数
DBMS_DDL          允许获取PL/SQL程序内部一定数量的DDL语句的过程
DBMS_DESCRIBE    为存储过程与函数描述API的过程
DBMS_JOB           管理BLOBs、CLOBs、NCLOBs与BFILEs的过程与函数
DBMS_OUTPUT        允许PL/SQL程序生成终端输出的过程与函数
DBMS_PIPE           允许数据库会话使用管道通信(通信频道)的过程与函数
DBMS_SQL           在PL/SQL程序内部执行动态SQL的过程与函数
DBMS_ULTILITY        DBMS_ULTILITY
ULT_FILE    允许PL/SQL程序读写服务器文件系统上的文本文件的过程与函数

39、如何解决单机监听不启动的问题:
你给IP固定一个值,然后配置NET8时最好用机器名,把listener.ora,tnsname.ora里的IP改成机器名。

40、查看日志文件的路径和数量:
select * from v$logfile;

41、oracle中的配置文件:
init.ora
tnsname.ora
listener.ora
sqlnet.ora

42、如何利用rownum 检索纪录:(在oracle中,只能通过rownum检索比rownum值小的所有的列)利用如下方法,可以检索表中rownum等于固定值的列:
select * from ( select rownum rn,column1,column2,… from table_name) where rn=要查询的值;

43、利用translate(char,from,to)函数判断一个字符串是否可以转换成 number 型:
translate(str,'x1234567890','x') is null,则str为纯字符串。
利用from to 参数,把str字段中所有的0-9的字符替换为空,然后判断函数返回值,返回值为空,则str一定可以转换成number型。

44、如何修改internal 用户的密码?
用法:orapwd file= password= entries=
参数解释:
    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.
1)进入DOS下
2)默认internal密码文件在c:\orant\database下,是隐藏属性,文件名称与数据库实例名有关
  如默认ORACLE实例名为ORCL,则internal密码文件名为pwdorcl.ora
3)建立新的internal密码文件,起个新名字为pwdora8.ora
  orapwd80 file=pwdora8.ora password=B entries=5     
--注:password项一定要用大写,并且不要用单引号
4)拷贝pwdora8.ora文件到c:\orant\database目录下
5)运行regedit,修改口令文件指向
6)找到HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE项
  定位ORA_ORCL_PWFILE子项,改变其值为c:\orant\database\pwdora8.ora
7)关闭ORACLE数据库,重新启动
Cool进入svrmgrl服务程序,测试internal密码是否更改成功

45、只有对象的拥有者才有对对象的操作权。如,把用户user1下的表tab_1赋给用户user2 查看的权限。此时,必须以uer1用户登陆,让后执行如下语句:
grant select on tab_1 to user2;

46、Oracle的本地进程    ps -aef | grep LOCAL=YES   的父进程ID不能为 1 ,若为 1 ,则该进程被掉死,需要用命令杀死改进程!!

47、在Windows 2000 server 操作系统下,用 net start 命令启动oracle的服务,如下:
net start OracleServiceORCL
net start OracleStartORCL
net start OracleTNSListener80
net start OracleWWWListener80
或者,利用 net stop 命令来终止服务:
net stop oraclestartorcl
net stop oracleserviceorcl
net stop oracletnslistener80

启动数据库的另外一个方法:
oradim -startup -sid SID
关闭数据库的另外一个方法:
oradim -shutdown -sid SID

48、多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表;内外表的选择可由公式:外层表中的匹配行数*内层表中每一次查找的次数确定,乘积最小为最佳方案。

49、保持Oracle数据库优良性能的若干诀窍:
1)    分区:
根据实际经验所得,在一个大数据库中,数据库空间的绝大多数是被少量的表所占有。如何简化大数据库和管理,如何改善应用的查询性能,一般可以使用分区这种手段。所谓分区就是动态地将表中记录分离到若干不同的表空间上,使数据在物理上被分割开来,便于维护、备份、恢复、事务及查询性能。当使用的时候可建立一个连接所有分区的视图,使其在逻辑上仍以一个整体出现。
(1)建立分区表
Create table Employee (
EmpNo varchar2(10) primary key,
Name varchar2(30),
DeptNo Number(2)
)
Partition by range(DeptNo)
(
partition PART1 values less than (11)
tablespace PART1_TS,
partition PART2 values less than (21)
tablespace PART2_TS,
partition PART3 values less than (31)
tablespace PART3_TS
partition PART4 values less than (MAXVALUE)
tablespace PART4_TS
);
表Employee依据DeptNo列进行分区。
(2)分区索引
Create index Employee_DeptNo on Employee(DeptNo)
local (
partition PART1 tablespace PART1_NDX_TS,
partition PART2 tablespace PART2_NDX_TS,
partition PART3 tablespace PART3_NDX_TS,
partition PART4 tablespace PART4_NDX_TS,
);
当分区中出现许多事务并且要保证所有分区中的数据记录的唯一性时采用全局索引,如:
Create index Employee_DeptNo on Employee(DeptNo)
global partition by range (DeptNo)
(
partition PART1 values less than (11)
tablespace PART1_NDX_TS,
partition PART2 values less than (21)
tablespace PART2_NDX_TS,
partition PART3 values less than (31)
tablespace PART3_NDX_TS
partition PART4 values less than (MAXVALUE)
tablespace PART4_NDX_TS
);
在建立全局索引时,global子句允许指定索引的范围值,这个范围值可以不同于表分区的范围值。只有建立局部索引才会使索引索引分区与表分区间建立起一一对应关系。因此,在大多数情况下,应该使用局部索引分区。若使用了此索引,分区就能够很容易地将索引分区与表分区建立关联,局部索引比全局索引更易于管理。
(3)分区管理
根据实际需要,还可以使用 alter table 命令来增加、丢弃、交换、移动、修改、重命名、划分、截短一个已存在分区的结构。

2)Rebuild Indexes(重建索引不会影响存储过程)
如果表中记录频繁的被删除或插入,尽管表中的记录总量保持不变,索引空间的使用量会不断增加。虽然记录从索引中被删除,但是该记录索引项的使用空间不能被重新使用。因此,如果表变化不定,索引空间量会不断增加,不管表中记录数量是否增加--只仅仅是因为索引中无效空间量的增加。
要回收那些曾被删除记录使用的空间,需要使用alter index rebuild 命令。可以做一个定期运行的批处理程序,来重建最活动表的索引。这个批处理程序可以在空闲时运行,以避免程序与用户冲突。若能坚持索引的这一程序规划,便可以及时回收那些未使用空间,提高空间利用率。

3)段的碎片整理
当生成一个数据库对象时(一个表或一个索引),通过用户缺省值或指定值来为它指定表空间。一个在表空间中所生成的段,用于存储对象的相关数据。在段被关闭、收缩、截断之前,段所分配的空间将不被释放。
一个段是由范围组成,而范围是由相邻的Oracle块组成。一旦存在的范围不能再存储新的数据,那这个段就会去获得新的范围,且并不要求这些范围是彼此相邻的。这样的扩展会一直继续下去,直到表空间中的数据文件不能提供更多的自由空间,或者范围数量已达到极限。
因此,一个碎片太多的数据段,不仅会影响运行,也会引发表空间中的空间管理问题。所以,每个数据段只含有一个范围是十分有益的。借助监控系统,可以通过检查DBA_SEGMENTS数据字典视图来了解哪些数据库对象含有10个或更多范围的段,确定其数据段碎片。
若一个段的碎片过多,可用两种方法解决这个问题:
(1)用正确的存储参数建立一个新表,将旧表中的数据插入到新表中,再删除旧表;
(2)利用Export/Import工具。
如:exp system/manager file=exp.dmp compress=Y grants=Y indexes=Y tables=(T1,T2)
若输出成功,进入Oracle,删除上述表。
注:compress=Y决定将在输出过程中修改它们的存储参数。
imp system/manager file=exp.dmp commit=Y buffer=64000 full=Y
注:在输入时重新配置新的存储参数。

自由范围的碎片整理
表空间中的一个自由范围是表空间中相连自由(空间)块的集合。当一个段关闭时,它的范围将被释放,并被标记为自由范围。然而,这些自由范围再也不能与相邻的自由范围合并,它们之间的界线始终存在。但是当表空间的缺省值pctincrease设置不为0时,SMON后台进会定期的将这些相邻的自由范围合并。若pctincrease设置为0,那相邻自由范围不会被数据库自动合并。但可以使用 alter tablespace 命令coalesce选项,来强迫进行相邻自由范围的合并。
不进行自由范围合并,在日后的空间请求中,会影响到表空间中的空间分配。当需要一个足够大的范围时,数据库并不会合并相邻的自由范围,除非没有其他选择。这样,当表空间中前面较小自由范围已被相关使用时,将使用表空间中后面部分最大的一个自由范围。结果,会因为它们没有足够多的使用空间,从而导致表空间中速度上的矛盾。由于这样的进程出现,使数据库的空间分配距理想越来越远。自由空间碎片常会出现在那些经常关闭又重新生成的数据库表和索引中。
在理想的ORACLE表空间中,每一个数据库对象存储在一个单独的范围中,并且所有有效自由空间集中在一个巨大而连续的范围中。这样,在一个对象需要附加存储空间时,可以在增加获取足够大自由空间的可能性同时,最小化空间中的循环调用,提高自由空间使用率

50、查看和修改Oracle服务器端字符集:
方法一:
1)    查看服务器端字符集:
select * from v$nls_parameters;
select * from nls_database_parameters;
select * from sys.props$;
2)    修改服务器端字符集(用sys用户):
首先执行:update props$ set value$ = 'WE8ISO8859P1' where name ='NLS_CHARACTERSET';
update props$ set value$ = 'china' where name ='NLS_LANGUAGE';
提交(commit),然后,重新启动数据库;
3)用客户端工具(PL/SQL DEVELOP or PB etc.)查询数据库,若显示乱码,先查询出数据库端的字符集,然后,从注册表中修改NLS_LANG字段的值,可能为AMERICAN_AMERICA.WE8ISO8859P1或者SIMPLIFIED CHINESE_CHINA.ZHS16GBK或者NA等。
方法二:
alter system enable restricted session;
alter database ORCL character set ZHS16GBK;
alter database ORCL national character set ZHS16GBK;

51、查看系统中的角色:
select * from dba_roles;

52、Import使用指南:
1)关键字缺省值:
Keyword   Description (Default)     Keyword       Description (Default)
-----------------------------------   ---------------------------------------
USERID   username/password          FULL       import entire file (N)
BUFFER   size of data buffer       FROMUSER     list of owner usernames
FILE     Input file (EXPDAT.DMP)   TOUSER       list of usernames
SHOW     just list file contents (N) TABLES       list of table names
IGNORE   ignore create errors (N)   RECORDLENGTH   length of IO record
GRANTS   import grants (Y)         INCTYPE     incremental import type
INDEXES   Import indexes (Y)       COMMIT       commit array insert (N)
ROWS     import data rows (Y)       PARFILE     parameter filename

Keyword                Description (Default)
-----------------------------------------------------------------------------
LOG                  log file of screen output
DESTROY                  overwrite tablespace data file (N)
INDEXFILE              write table/index info to specified file
CHARSET                  character set of export file (NLS_LANG)
POINT_IN_TIME_RECOVER      Tablespace Point-in-time Recovery (N)
SKIP_UNUSABLE_INDEXES      skip maintenance of unusable indexes (N)
ANALYZE                  execute ANALYZE statements in dump file (Y)
FEEDBACK                display progress every x rows(0)
VOLSIZE                  number of bytes in file on each volume of a file on tape
说明:
1)如果导出用户没有DBA权限,则导入用户可以不用指定fromuser、touser参数 ;
2)如果导出用户拥有DBA权限,则导入用户也必须拥有DBA权限;

53、常用的SQL关键字:
1)UNION:返回两个查询结果并去除其中重复的部分;
2)UNION ALL:返回两个查询结果但是并不去除重复的纪录;
3)INTERSECT:返回两个表中共有的行;
4)MINUS:返回第一个表中存在的但是第二个表中不存在的纪录;
5)BETWEEN … AND …:返回…和…之间的值,包括边界值;

54、常用的SQL一些函数:
1)ADD_MONTHS(column_name,number_value):在当前的日期上增加number_value个月;
注:column_name 为日期型;number_value 为整型数值;
2)LAST_DAY(column_name):返回当前月的最后一天;
注:column_name 为日期型;
3)MONTHS_BETWEEN(column_a,column_b):返回两个日期间月份的个数;
4)NEXT_DAY(column_name,'SUNDAY[MONDAY,TUESDAY,WEDNESDAY,THURSDAY, FRIDAY,…]'
5)    LPAD(column_name,number_value,'fill_character')
6)    RPAD(column_name,number_value,'fill_character')
7)    LTIRM(column_name[, fill_character])
8)    RTRIM(column_name[,fill_character])
9)    REPLACE(column_name,'old_stings'[,'new_strings'])
10)SUBSTR(column_name,number_start,number_count)
11)TRANSLATE(column_name,'origin_characters','translate_into_characters')
12)INSTR(column_name,'strings_to_search',number_1,number_2)
strings_to_seach:将要搜索的字符串;
number_1:从第number_1个字符开始查找;
number_2:返回第number_2个字符串首字符的位置;
13)LENGTH(column_name):返回字符串的长度;
14)TO_CHAR()
15)TO_NUMBER()
16)GREATEST(var_1,var_2,var_3,…)
17)LEAST(var_1,var_2,var_3,…)
18)USER:返回当前使用数据库的用户名字;

55、
1)    GROUP BY:
当要求分组结果返回多个数值时,不能在select 语句中使用使用除分组列以外的列,这将会导致错误的返回值,你可以使用select 语句中未列出的列进行分组;
2)    HAVING:
汇总函数不能工作在WHERE 子句中,HAVING 允许将汇总函数作为条件,代替WHERE子句;
3)    STARTING WITH:
等同于LIKE;

56、关于sys用户以sysdba的身份登陆的一些注意事项:
1)把sysdba系统权限与dba角色要分开,不要混淆,有dba角色不一定是sysdba;
2)在server上可能用了操作系统认证,用了操作系统认证就不能在本机上以sysdba身份登但是可以在client上测试;
3)    把INIT.ORA中REMOTE_LOGIN_PASSWORD设置为EXCLUSIVE 或SHARED。同时把sqlnet.ora文件中SQLNET.AUTHENTICATION _SERVICES设置为NONE或注释后,然后在服务器上进行测试,就可以通过;
4)查看系统中具有sysdba权限的用户:select * from v$pwfile_users;

57、给数据库中的表和列加上注释:
comment on table Table_name is '注释的内容';
comment on column Table_name.column_name is '注释内容';
查看表的注释:
select * from user_tab_comment;
查看列的注释:
select * from user_col_comment;
其他于此相关的视图:
dba_tab_comments、dba_col_comments;

58、P4机器的安装问题
在基于奔四的Windows 2000系统上安装Oracle8i数据库时有可能产生错误,症状为单击Setup.exe时没有反应。这是因为Oracle8i的安装程序不能识别Intel的奔四处理器。可按照以下方法来解决这个问题:
(1) 安装最新的Windows 2000服务包补丁程序(如sp2,sp3等),可在http://www.microsoft.com/ windows2000/downloads/上下载;
(2) 在奔四服务器上创建一个临时目录(e.g. \TEMP);
(3) 将Oracle数据库服务器安装光盘的所有内容拷贝到第二步创建的临时目录中;
(4) 在第二步创建的临时目录里搜索名为SYMCJIT.DLL的文件;
(5) 把SYMCJIT.DLL修改为SYMCJIT.OLD;
(6) 从\TEMP\install\win32目录运行SETUP.EXE来安装Oracle 8.1.x。

59、手工编译存储过程、触发器:
alter procedure procedure_name complile;
alter trigger trigger_name compile;

60、
1)给表中的某个字段加上主键约束:
alter table tabl_name add constraint primary_key_name primary key(column_name);
2)删除表中的主键约束:
alter table table_name drop primary key cascade;
alter talbe table_name drop constrain constraint_name cascade;

61、查看快照:
select * from user_snapshots

62、
1)改变回滚段的大小:
alter rollback segment rbs_name shrink to nnM;
2)合并自由表空间:
alter tablespace tablespace_name coalesce;
3)改变表空间数据文件的大小:
alter database datafile '$path$\datafile_name' RESIZE nnM;

63、
1)数据库名称:
select * from v$database;
select * from global_name;
2)实例名称:
select * from v$instance;

64、ORADER BY 和 GROUP BY 的一些关系:
一个SQL语中有Group By语句,那么Order By中的表达式就必须是在Group By中出现过。

65、对大于2G的数据库如何解决操作系统最大文件为2G的限制?
可以利用如下方法,把导出的dmp文件保存到多个文件中:
exp user_name/password filesize=1999M
file=\(/home1/back0/user_infor_0.dmp,/home1/back0/user_infor_1.dmp\) log=/home1/back0/user_infor_X   tables=user_table_name
(如果要导出整个用户下的数据,则把tables=user_table_name替换为full=y)

65、Orale数据库中的数据字典:
View    ODBC API    OLE DB API
ALL_CATALOG    SQLTables    DBSCHEMA_CATALOGS
ALL_COL_COMMENTS    SQLColumns    DBSCHEMA_COLUMNS
ALL_CONS_COLUMNS    SQLPrimaryKeys, SQLForeignKeys    DBSCHEMA_PRIMARY_KEYS, DBSCHEMA_FOREIGN_KEYS
ALL_CONSTRAINTS    SQLPrimaryKeys, SQLForeignKeys    DBSCHEMA_PRIMARY_KEYS, DBSCHEMA_FOREIGN_KEYS
ALL_IND_COLUMNS    SQLStatistics    DBSCHEMA_STATISTICS
ALL_INDEXES    SQLStatistics    DBSCHEMA_STATISTICS
ALL_OBJECTS    SQLTables, SQLProcedures, SQLStatistics    DBSCHEMA_TABLES, DBSCHEMA_PROCEDURES, DBSCHEMA_STATISTICS
ALL_TAB_COLUMNS    SQLColumns    DBSCHEMA_COLUMNS
ALL_TAB_COMMENTS    SQLTables    DBSCHEMA_TABLES
ALL_TABLES    SQLStatistics    DBSCHEMA_STATISTICS
ALL_USERS    SQLTables    DBSCHEMA_TABLES
ALL_VIEWS    SQLTables    DBSCHEMA_TABLES
DICTIONARY    SQLTables    DBSCHEMA_TABLES
USER_CATALOG    SQLTables    DBSCHEMA_TABLES
USER_COL_COMMENTS    SQLColumns    DBSCHEMA_COLUMNS
USER_CONS_COLUMNS    SQLPrimaryKeys, SQLForeignKeys    DBSCHEMA_PRIMARY_KEYS, DBSCHEMA_FOREIGN_KEYS
USER_CONSTRAINTS    SQLPrimaryKeys, SQLForeignKeys    DBSCHEMA_PRIMARY_KEYS, DBSCHEMA_FOREIGN_KEYS
USER_IND_COLUMNS    SQLStatistics    DBSCHEMA_STATISTICS
USER_INDEXES    SQLStatistics    DBSCHEMA_STATISTICS
USER_OBJECTS    SQLTables, SQLProcedures, SQLStatistics    DBSCHEMA_TABLES, DBSCHEMA_PROCEDURES, DBSCHEMA_STATISTICS
USER_TAB_COLUMNS    SQLColumns    DBSCHEMA_COLUMNS
USER_TAB_COMMENTS    SQLTables    DBSCHEMA_TABLES
USER_TABLES    SQLStatistics    DBSCHEMA_STATISTICS
USER_USERS    SQLTables    DBSCHEMA_TABLES
USER_VIEWS    SQLTables    DBSCHEMA_TABLES

66、查询系统中的数据库连接:(Database Link)
select * from user_db_links;

67、如何单独从Oracle数据库中备份多个用户?
exp system/manager wner=(用户1,用户2,…,用户n) file=导出文件;

68、如何备份一个或多个表?
Exp system/manager tables=(用户1.表1,\
       用户1.表2,\
       用户1.表3,\
       ……
       用户2.表n+1,\
       用户2.表n+2,\
       用户2.表n+3
……)

69、如何导入指定的表?
Imp user_name/password fromuser=dmp_user_name touser=user_name tables=… file=…
注释:
1)果导出用户没有DBA权限,则导入用户可以不用指定fromuser、touser参数
2)    如果导出用户拥有DBA权限,则导入用户也必须拥有DBA权限

70、如何备份控制文件?
1)产生一个跟踪文件,里面存放创建控制文件的脚本,可以用记事本等文本编辑器打开
这个脚本可以重新创建控制文件,生成一个跟踪文件到init.ora中user_dump_dest所指的目录下($ORACLE_HOME\ADMIN\ORADB\UDUMP\):
Alter database backup controlfile to trace;
Alter database backup controlfile to trace resetlogs;
Alter database backup controlfile to trace noresetlogs;
2)产生一个二进制文件,当前控制文件的一个一模一样的备份:
alter database backup controlfile to 文件名;
alter database backup controlfile to 文件名 reuse;

71、如何移动控制文件到一个新的目录?
1)SHUTDOWN
2)用操作系统命令将C:\Oracle\oradata\oradb\control01.ctl拷贝到新的目录:
  D:\Oracle\oradb\data,
  则现在控制文件的完整路径为:D:\Oracle\oradb\data\control01.ctl,
  修改init.ora文件,在control_files参数中改变控制文件的路径,
  修改前
  control_files = ("C:\Oracle\oradata\oradb\control01.ctl")
  修改后
  control_files = ("D:\Oracle\oradb\data\control01.ctl")
3)STARTUP

72、存储参数(storage子句)含义及设置技巧
该子句可用于:表空间、回滚段、表、索引、分区、快照、快照日志,具体应用如下:
参数名称    缺省值    最小值    最大值    说明
INITIAL    5(数据块)    2(数据块)    操作系统限定    分配给Segment的第一个Extent的大小,以字节为单位,这个参数不能在alter语句中改变,如果指定的值小于最小值,则按最小值创建。
NEXT    5(数据块)    1(数据块)    操作系统限定    第二个Extent的大小等于NEXT的初值,以后的NEXT值=前一NEXT大小乘以(1+PCTINCREASE/100),如果指定的值小于最小值,则按最小值创建。
如果在alter语句中改变NEXT的值,则下一个分配的Extent将具有指定的大小,而不管上一次分配的Extent大小和PCTINCREASE参数值。
MINEXTENTS    1(Extent)
回滚段为2个Extent    1(Extent)
回滚段为2个Extent    操作系统限定    Segment第一次创建时分配的Extent数量
MAXEXTENTS    根据数据块大小而定    1(Extent)
回滚段为2个Extent    无限制    随着Segment中数据量的增长,最多可分配的Extent数量
PCTINCREASE    50%(Oracle816中为0%)    0%    操作系统限定    指定第三个及其后的Extent相对于上一个Extent所增加的百分比,
如果PCTINCREASE为0,则Segment中所有新增加的Extent的大小都相同,等于NEXT的值,
如果PCTINCREASE大于0,则每次计算NEXT的值(用上面的公式),
PCTINCREASE不能为负数。
创建回滚段时,不可指定此参数,回滚段中此参数固定为0。
OPTIMAL    ----    不能小于回滚段初始分配空间    操作系统限定    仅与回滚段有关,当回滚段因为增长、扩展而超过此参数的设定范围时,Oracle系统会根据情况动态地重新分配Extents,试图收回多分配的Extent。
               
FREELISTS    1    1    数据块大小限制    只能在CREATE TABLE、CLUSTER、INDEX中指定FREELISTS和FREELIST GROUPS参数。
模式对象中每一个自由列表组中自由列表的数量
FREELIST GROUPS    1    1    取决于Oracle并行实例的数量    用户创建的数据库对象的自由列表组的数量,只有用OPS并行服务器选项时才使用这一参数,一个实例对应一个组。
BUFFER_POOL    ----    ----    ----    给模式对象定义缺省缓冲池(高速缓存),该对象的所有块都存储在指定的高速缓存中,对于表空间或回滚段无效。

建议PCTINCREASE参数设置为0,可使碎片最小化,使每一个Extent都相同(等于NEXT值)
一旦建立了某个对象,它的INITIAL和MINEXTENTS参数不能修改(Oracle 816中可修改MINEXTENTS参数)
对于NEXT和PCTINCREASE的任何修改都只影响后来分配的那些Extent
在分配一个新Extent时,系统直接按NEXT的值分配一个Extent,
然后用公式:前一NEXT值*(1+PCTINCREASE/100) 计算出下一个应该分配的Extent的大小,
并把计算结果保存到相关数据字典的NEXT_EXTENT列上,做为下一个应该分配的Extent的大小。

73、查看系统后台进程:
select * from v$bgprocess;
SMON    系统进程
PMON    用户进程
DBWR    数据库写入进程
LGWR    日志写入进程
CKPT    检查点进程        用来减少实例恢复所需时间,
   init.ora中,log_checkpoint_interval = 10000,此参数设置检查点出现的频度
ARCH    归档进程        将联机重做日志拷贝到磁盘或磁带,即将联机重做日志归档
RECO    恢复进程        用于分布式数据库中的分布式处理,
   init.ora中,distributed_transactions = 10,此参数大于0时才被建立
SNPn    快照进程        数量取决于init.ora中参数job_queue_processes = 4
LCKn    锁进程            可选项,用于并行服务器
Dnnn    调度进程        可选项,仅用于多线程服务器

74、如何启动archivelog模式?
1)管理器:
>connect internal
>shutdown     --若执行了shutdown abort则需要重新startup,然后再正常shutdown
>startup mount [dbname]
>alter database [dbname] archivelog;
>archive log start
>alter database [dbname] open;
>alter system switch logfile;   --强制系统进行日志切换,可马上观察到归档日志的产生;
>exit
2)    改数据库初始化参数文件,定义归档模式(自动)、归档日志保存路径归、档日志命名方法。
3)    重新启动数据库;

解释init.ora参数文件中关于归档重做日志参数项的含义
归档模式是自动还是手工,true为自动,false为手工
log_archive_start = true
归档日志文件所保存的路径
log_archive_dest_1 = "location=C:\Oracle\oradata\oradb\archive"
归档日志文件的命名方法
log_archive_format = %%ORACLE_SID%%T%TS%S.ARC
归档命令:
启动自动归档模式,系统重起后,将按init.ora中的参数log_archive_start的值设置归档方式
SVRMGR> archive log start
启动手工归档模式
SVRMGR> archive log stop
查看归档信息:重做日志是否归档方式、是自动归档还是手工归档、归档路径、最旧的联机日志循序号...
SVRMGR> archive log list
归档一个已满,但没有归档的联机重做日志
SVRMGR> archive log next
归档所有已满,但没有归档的联机重做日志
SVRMGR> archive log all
注意:一个事务即使不被提交,也会被写入到重做日志中

停用归档日志模式:
alter database [db_name] noarchivelog;

75、Oracle数据库有哪几种启动方式?
有以下几种启动方式:
1)startup nomount
  非安装启动,这种方式启动下可执行:重建控制文件、重建数据库
  读取init.ora文件,启动instance,即启动SGA和后台进程,这种启动只需要init.ora文件。
2)startup mount dbname
  安装启动,这种方式启动下可执行:
  数据库日志归档、
  数据库介质恢复、
  使数据文件联机或脱机,
  重新定位数据文件、重做日志文件。
  执行"nomount",然后打开控制文件,确认数据文件和联机日志文件的位置,
  但此时不对数据文件和日志文件进行校验检查。
3)startup open dbname
  先执行"nomount",然后执行"mount",再打开包括Redo log文件在内的所有数据库文件,
  这种方式下可访问数据库中的数据。
4)startup,等于以下三个命令
  startup nomount
  alter database mount
  alter database open
5)startup restrict
  约束方式启动
  这种方式能够启动数据库,但只允许具有一定特权的用户访问
  非特权用户访问时,会出现以下提示:
  ERROR:
  ORA-01035: ORACLE 只允许具有 RESTRICTED SESSION 权限的用户使用
6)startup force
  强制启动方式
  当不能关闭数据库时,可以用startup force来完成数据库的关闭
  先关闭数据库,再执行正常启动数据库命令
7)startup pfile=参数文件名
  带初始化参数文件的启动方式
  先读取参数文件,再按参数文件中的设置启动数据库
  例:startup pfile=E:\Oracle\admin\oradb\pfile\init.ora
8)startup EXCLUSIVE

76、如何查看SGA剩余的内存?
select name,sgasize/1024/1024 "Allocated(M)",bytes/1024 "自由空间(K)", round(bytes/sgasize*100,2) "自由空间百分比(%)" from   (select sum(bytes) sgasize from sys.v_$sgastat) s, sys.v_$sgastat f where f.name = 'free memory';

77、存储过程/函数只能被赋予执行的权限:
grant execute on procedure_name/function_name to user_name;

78、如何把一个表空间授权给一个用户?
Alter user quota on ;

79、快照(snapshot):
快照,也叫物化的视图,Oracle在复制环境中利用快照复制数据到备份服务器中,目的是缓解一个大的数据仓库中昂贵的查询开销。
A snapshot is a replica of a target master table from a single point in time.
Snapshot can also contain a where clause so that snapshot site can contain custermized data sets.
创建一个快照:
CREATE SNAPSHOT emp_snap AS SELECT * FROM scott.emp@db1.world;
1)Primary key snapshot are default type of snapshot:
CREATE SNAPSHOT sales.customer FOR UPDATE AS SELECT * FROM sales.customer @dbs1.acme.com;
2)为了向后兼容Oracle支持ROWID Snapshots(only supported by oracle7)
3)    omplex Snapshots,支持connect by、intersect、union、minus etc。

80、如何对CLOB行字段执行全文检索?
超过4000字的文本一般存储在CLOB中(MSQL、Sysbase是存放在Text中),在目前的Oracle版本(Oracle8i)中,对大字段CLOB仍然不支持在where子句直接的like操作,如何实现对存储在CLOB字段中的内容进行like查找呢?下面的文章也许能给你帮助。虽然在SQL*PLUS中能实现用select直接看到CLOB的内容,但是如何通过DBMS_LOB包实现对中文环境下的CLOB内容的读取我一直没有找到好的方法(使用Documents中提到的Samples只适用英文字符集),这极大的限制了使用第3方软件开发工作的自由度。
表结构:
create table products(
productid number(10) not null ,
name varchar2(255) ,
description CLOB) ;
方法:
SELECT productid, name FROM products
WHERE dbms_lob.instr(products.description,'some text',1,1) > 0;

下面列出了DBMS_LOB包中的过程函数:
APPEND procedure Appends the contents of the source LOB to the destination LOB.
CLOSE procedure Closes a previously opened internal or external LOB.
COMPARE function Compares two entire LOBs or parts of two LOBs.
COPY procedure Copies all, or part, of the source LOB to the destination LOB.
CREATETEMPORARY procedure Creates a temporary BLOB or CLOB and its corresponding index in the user's default temporary tablespace.
ERASE procedure Erases all or part of a LOB.
FILECLOSE procedure Closes the file.
FILECLOSEALL procedure Closes all previously opened files.
FILEEXISTS function Checks if the file exists on the server.
FILEGETNAME procedure Gets the directory alias and file name.
FILEISOPEN function Checks if the file was opened using the input BFILE locators.
FILEOPEN procedure Opens a file.
FREETEMPORARY procedure Frees the temporary BLOB or CLOB in the user's default temporary tablespace.
GETCHUNKSIZE function Returns the amount of space used in the LOB chunk to store the LOB value.
GETLENGTH function Gets the length of the LOB value.
INSTR function Returns the matching position of the nth occurrence of the pattern in the LOB.
ISOPEN function Checks to see if the LOB was already opened using the input locator.
ISTEMPORARY function Checks if the locator is pointing to a temporary LOB.
LOADFROMFILE procedure Loads BFILE data into an internal LOB.
OPEN procedure Opens a LOB (internal, external, or temporary) in the indicated mode.
READ procedure Reads data from the LOB starting at the specified offset.
SUBSTR function Returns part of the LOB value starting at the specified offset.
TRIM procedure Trims the LOB value to the specified shorter length.
WRITE procedure Writes data to the LOB from a specified offset.
WRITEAPPEND procedure Writes a buffer to the end of a LOB

81、
Oracle SQL运行时间的最主要的组成部分是花在为执行准备新的SQL语句上的时间。不过,如果了解了可执行计划产生的内在机制,你就可以控制Oracle花费在评估表的连接顺序的时间,并在总体上提高查询的性能。
1)准备为执行提供的SQL语句
在一个SQL语句进入Oracle库的cache之后、而真正被执行之前,将会依次发生如下事件:
语法检查--检查该SQL语句的拼写和词序是否正确。
语义解析--Oracle根据数据词典(data dictionary)来验证所有的表格(table)和列(column)。
已保存纲要检查--Oracle检查词典以确认对应该SQL语句是否已存在已保存的纲要(Stored Outline)。
产生执行计划--Oracle根据一种罚值(cost-based)优化算法和数据词典中的统计数据来决定如何生成最优执行计划。
产生二进制代码--Oracle在执行计划的基础上生成可执行的二进制代码。
一旦开始准备执行SQL语句,上述的过程很快就会执行,这是因为Oracle可以识别出同样的SQL语句并对同样的SQL语句重复使用对应的可执行代码。然而,对产生ad hoc SQL的系统以及SQL中嵌入文本值(literal value)的情况,SQL执行计划的生成时间就会变得相当长,而且以前的执行计划也常常不能被再次利用。对那些牵涉到许多表格的查询,Oracle可能要花上很长的时间来决定把连接这些表格的顺序。
2)评估连接表格的顺序
生成可执行计划的时间往往是SQL的准备过程中最大的开销组成部分,尤其是在处理有多个表的连接的查询的情况下。当Oracle评估表的连接顺序时,它必须考虑每一种可能的排序。例如,当有六个表格需要连接时,Oracle需要考虑720种(6的排列数,即6×5×4×3×2×1=720)可能的连接排序。当需要连接的表的数量超过10时,这个排列问题将变得非常突出:如果需要连接的表格有15个,那么需要考虑的可能的查询排列顺序超过一万亿种(精确值为1,307,674,368,000)。
在optimizer_search_limit参数中设置限制
你可以通过optimizer_search_limit参数来控制上述问题的发生,该参数用来指定优化器评估的表格连接顺序的最大数目。利用这个参数,就可以防止优化器在评估所有可能的表格连接顺序中所花费的多余时间。如果查询中的表的数量少于或者等于optimizer_search_limit,那么优化器检查所有的可能表的连接方式。
例如,涉及了五个表的查询一共有120种(5!=5×4×3×2×1=120)可能的连接顺序,所以如果参数optimizer_search_limit的值设置为5(默认值),那么优化器就会考虑所有的这120种可能的连接顺序。optimizer_search_limit参数还用来控制启动开始连接指示(star join hint)的阈值。当查询所涉及的表格数量少于参数optimizer_search_limit的设定值,开始连接指示将被设置。

82、DECODE的用法:
decode(expr, value1, result1,
        value2, result2,
        ....
        valueN, resultN,
        default_result)

当expr=valueN的时候,返回resultN,否则返回default_result;

83、DUAL在ORACLE数据库里代表什么?是一个系统表么?
一个临时表,由系统创建的。

84、select * from user_objects where status<>'VALID';
alter package package_name compile ; --编译包
alter package package_name compile body; --仅编译包体

85、从oracle数据库中导出数据,若是按用户导出数据,最后一步提示如下:
About to export specified users ...
User to be exported: (RETURN to quit) >
此时,必须至少输入一个用户,如zbtel,输入用户并回车后,又出现如下提示:
User to be exported: (RETURN to quit) >
若此时按回车键,则仅仅导出用户zbtel下的数据;
若不按回车,又输入用户zbnet,按回车,又出现如下提示:
User to be exported: (RETURN to quit) >
此时再按回车,则导出用户zbtel、zbnet下的数据;
以此类推,可以导出数据库中部同用户的数据。

86、、drop user user_name cascade;
When a user is dropped, the user and associated schema is removed from the data dictionary and all schema objects contained in the user's schema, if any, are immediately dropped.
A user that is currently connected to a database cannot be dropped. To drop a connected user, you must first terminate the user's sessions using either Enterprise Manager/GUI, or the SQL command ALTER SYSTEM with the KILL SESSION clause.
If the user's schema contains any schema objects, use the CASCADE option to drop the user and all associated objects and foreign keys that depend on the tables of the user successfully. If you do not specify CASCADE and the user's schema contains objects, an error message is returned and the user is not dropped.

87、viewing memory using per user session
SELECT username, value || 'bytes' "Current session memory"
  FROM v$session sess, v$sesstat stat, v$statname name
WHERE sess.sid = stat.sid
  AND stat.statistic# = name.statistic#
  AND name.name = 'session memory';

88、
锁定一个用户:alter user scott account lock;
解锁一个用户:alter user scott account unlock;

89、给用户授权:grant privs_1,privs_2,… session to user_name;
解除给用户的授权:revoke privies_1,privies_2,… session from user_name;
给用户赋予角色:grant role_1,role_2,… to user_name;
收回赋予用户的角色:revoke role_1,role_2,… from user_name;

90、dynamic performance views:
Dynamic performance views provide data on internal disk structures and memory structures. These views can be selected from, but never updated or altered by the user.

91、在sql/plus中的一种计算某个表中的一种记录占整个表的所有记录数的比例的方法:
select a.cnt/b.cnt
from
(select count(*) cnt from subscriber where subsname like '秦%') a,
(select count(*) cnt from subscriber ) b;

92、在提交某一事物之前,设置事物的回滚段:
   SET TRANSACTION USE ROLLBACK SEGMENT RBS_name;
注:设置回滚段必须在某个事务之前设定,并且进对当前事务发生作用,当事务提交(commit)后,设置自动取消作用。

93、查看又户下的所有的表以及该表使用的表空间:
   select * from user_talbes;
   查看系统所有用户的表以及相应的表使用的表空间:
   select * from dba_talbes;
注:表user_tables和表dba_tables中的表的名称都是大写的。

94、用sql语句在数据库中的某个表检索数据时,建立了主索引的列一定要放在最前,这样会提高系统的运行速度。

95、向一个已经存在的表中增加一列,用如下命令:
   alter talbe tab_name add(column_name column_type,
                       column_name column_type……);

96、改变一个已经存在的表的列(modify):   
ALTER TABLE tab_name
         MODIFY (column_name DEFAULT NULL);

97、改变表的pctfree,pctused的值:
   alter table tab_name pctfree value_a pctused value_b;

98、主键约束:
   主键列的值必须唯一;
   主键列不能又空值;
   一个表只能有一个主键;
A primary key column cannot be of datatype LONG or LONG RAW. You cannot designate the same column or combination of columns as both a primary key and a unique key or as both a primary key and a cluster key. However, you can designate the same column or combination of columns as both a primary key and a foreign key.

99、用一个已经存在的表创建一个新表:
   复制一个新表:
   create table new_table as ( select * from old_table);
   创建一个包含原表部分字段的新表:
   create table new_table as (select column_1,column_2,column_3 from old_table);
   注意:用create table new_table as (select * from old_table)创建新表时,旧表的默认值不能利用该命令传递,即即使旧表的有不为空的缺省值,新表的缺省值也为空,即表的索引、约束等都不被传递。

100、一个关于PCTFRREE、PCTUSED、ROW Chaining的简单介绍
Two space management parameters, PCTFREE and PCTUSED, enable you to control the use of free space for inserts of and updates to the rows in all the data blocks of a particular segment. You specify these parameters when creating or altering a table or cluster (which has its own data segment). You can also specify the storage parameter PCTFREE when creating or altering an index (which has its own index segment).
The PCTFREE parameter sets the minimum percentage of a data block to be reserved as free space for possible updates to rows that already exist in that block.
The PCTUSED parameter sets the minimum percentage of a block that can be used for row data plus overhead before new rows will be added to the block. After a data block is filled to the limit determined by PCTFREE, Oracle considers the block unavailable for the insertion of new rows until the percentage of that block falls below the parameter PCTUSED. Until this value is achieved, Oracle uses the free space of the data block only for updates to rows already contained in the data block.

101、在调用一个带有多个默认参数的过程中,如果使用按名称对应法则,可以任意指定参数的值,不必理会参数在过程中的位置;而如果使用了按位置的对应法则,则必须按照严格的位置指定参数值,一旦某个参数使用了缺省值,则该参数后的所有的参数都必须是缺省值。

102、过程与函数:
   在执行的结果要求有多个返回值的时候,用过程;
   在执行的结构只有一个返回值的时候,可用函数;

103包:包是由存储在一起的相关对象组成的PL/SQL结构。
   包包括说明部分和包体,这两部分独立存储在数据词典中。

104、取消表tab_test中的col_test列的缺省值:
   alter table tab_test modifty(col_test default null);
   允许或取消表tab_test的col_test列的值可以为空:
   alter table tab_test modify(col_test null);
   alter table tab_test modify(col_test not null);

105、用import向一个数据库中导入数据的时候,import指定的表在新的数据库中必须是不存在的,若存在,需要drop掉。

106、user_triggers是系统的一个视图,可以查看系统触发器的详细信息:
select 'alter trigger '|| TRIGGER_NAME ||' disable;' from user_triggers;
select 'alter trigger '|| TRIGGER_NAME ||' enable;' from user_triggers;

107、ORACEL8的TNS服务不能启动时,首先要检查网络是否畅通,然后,进入lsnrctl,执行stop命令,查找出错误的原因,然后执行start命令,若未成功,可修改$ORACLE_HOME\network\admin\listernerl.ora文件,然后再次执行start命令。

108、用exp导出文件,若要将该文件导入到另外一个库的某个用户下,导出数据用户的权限要与导入的用户具有相同的权限或者后者的权限大于前者的权限。

109、从几个表中通过关联取部分字段插入一个新表的时候,可以用如下方式:
   select tab_1.col1,tab_2.col2 from tab_1,tab_2 where tab_1.col3 =tab_2.col3 ;
   用pb,把选择出来的数据保存成文本格式,然后,仍然利用pb,retrieve将要插入的表,从菜单中选择“Rows”,“Import”,选择保存好的文本文件,打开,然后从按钮栏上单击“save changes”图标。(注:导入数据的表必须有主键约束或唯一性索引)

110、从一个ORACLE数据库直接向另外一个ORACLE数据库中导数据,方法如下:
   首先,建立一个数据库链接,并赋予别名:
   create [public] database link 要连接的数据库实例名
       connect to 用户名 identified by 密码
       using ‘数据库链接字符串’;
   删除数据库连接:
   drop [public] database link database_link_name;
   注意:
1)    数据库链接字符串是用NET8 EASY CONFIG或者直接修改TNSNAMES.ORA里定义的。数据库参数global_name=true时要求数据库链接名称跟远端数据库名称一样。数据库全局名称可以用以下命令查出SELECT * FROM GLOBAL_NAME。在global_name=ture时,若数据库名称后面没由域名,需要用如下语句改变global_name的名称:
alter database rename global_name to 数据库名称.域名;
Use the ALTER DATABASE statement to change the domain in a database's global name. Note that after the database is created, changing the initialization parameter DB_DOMAIN has no effect on the global database name or on the resolution of database link names.
2)    要连接的数据库实例名必须是数据库全局名称,即用SELECT * FROM GLOBAL_NAME选出来的字符串。
   
   要选择数据库的表中的数据,如下:
       select * from table_name@要连接的数据库实例名;
   表与表之间的拷贝为:
       insert into local_table_name (select * from table_name@数据库链接名);

111、Oracel 中 How to terminate a session?
   alter system kill session 'sid,serial#';

112、查看当前链接地数据库:
   select global_name from global_name;

113、查看SGA的大小:
   select * from v$sga;
114、增加一个表空间(tablespace)的大小:
   alter database datafile 'filename' resize nn M;
   或者
   alter tablespace tablespace_name add datafile 'filename' size nn M;
   (Make sure you specify the full path name for the filename.)
115、用sql查询Oracle数据库中地一些属性:
--LIST DB NAME
SELECT * FROM GLOBAL_NAME;
--LIST TABLESPACES
select tablespace_name,max_extents,pct_increase,status from dba_tablespaces;
--LIST DB DATA FILES
column tablespace_name format A16;
column file_name format A46;
select * from dba_data_files;
--LIST TABLEASPACE USAGE
select * from( select tablespace_name,sum(bytes)/(1024*1024) as "free_space(M)"
from dba_free_space
group by tablespace_name) order by "free_space(M)";
--LIST ROLLBACK SEGMENT
column segment_name format A10;
column tablespace_name format A16;
column status format A10;
select segment_name,tablespace_name, r.status,
(initial_extent/1024) "InitialExtent(K)",
(next_extent/1024) "NextExtent(K)",
max_extents "max_extents(K)", v.curext "CurExtent(K)"
From dba_rollback_segs r, v$rollstat v
Where r.segment_id = v.usn(+)
order by segment_name;
--LIST CONTROL FILES
select name "control file name" from v$controlfile;
--LIST LOG FILES
select member "log file name" from v$logfile;
--LIST VERSION OF ORACLE
Select version "oracle version" FROM Product_component_version
Where SUBSTR(PRODUCT,1,6)='Oracle';
--LIST CREATED DATE AND LOG_MODE OF ORACLE
Select Created "db created time", Log_Mode From V$Database;
--LIST SGA SIZE
select sum(value)/(1024*1024) "sga size" from v$sga;
--LIST CUREENT SESSIONS
select count(*) "current user number",username "current username" from v$session group by username;

--LIST DB USERS AND THEIR DEFAULT TABLESPACE
select username,default_tablespace,temporary_tablespace from dba_users;
-- list quota of users
select * from DBA_TS_QUOTAS order by Tablespace_Name, Username;
--LIST REPORT TIME
select sysdate "report time" from dual;

116、RollBack Segment是ORACLE里很特殊地一种数据库对象,它处理事务回滚操作。通常,一般需要并发ORACLE用户数/4个RollBack Segment,用Private类型。
   select name,value from v$parameter where instr(name,'rollback')>0;
创建一个回滚段:
create rollback segement rbs_05tablespace rbs storage (initial 128k next 128k minextents 20);
   alter rollback segment rbs_05 online;
   rollback segemt 缺省的存储参数:pctincrease 0 minextents 偶数
                    maxextent跟数据库的块大小有关
                          2K     121
                          4K     249
                          8K     505
针对某个特定的大事务操作,如update大量数据时,可以建一个大的rollback segment,如:
create rollback segment rte tablespace rbs storage (initial 5M next 5M minextents 20);
   alter rollback segment rte online;
改数据库参数文件 init(oraid).ora
   rollback_segments = (r01, r02, r03, r04,r05,r06,r07,r08,r09,r10,r11,r12,rte)
重启数据库,新建的rollback_segment才生效
把大事务操作指给大的回滚段rte
   commit;
   set transaction use rollback segment rte;
   ...... ;
   .
   .
   commit;

117、重命名一个表:
   alter table table_name_old rename to table_name_new;
   或者
   rename old_table_name to new_table_name;

118、查看当前用户的角色(role):
   select * from user_role_privs;

119、查看当前用户缺省表空间:
   select username,default_tablespace from user_users;

120、查看当前用户的系统权限和表级权限:
   select * from user_sys_privs;
   select * from user_tab_privs;

121、查看用户下的所有表:
   select * from user_tables;

122、查看当前用户下的所有对象:
select * from user_objects;

123、查看某表的创建时间:
select object_name,created from user_objects where
object_name=upper('&object_name');

124、查看某表的大小
   select sum(bytes)/(1024*1024) as "size(M)" from user_segments where segment_name=upper('&table_name');
  (注:user_sgments中的行数=user_tables中的行数+user_indexes中的行数)

125、查看ORACLE放在内存区里的表:
   select table_name,cache from user_tables where instr(cache,'Y')>0;

126、查看索引的个数和类别:
   select index_name,index_type,table_name from user_indexes order by table_name;

127、查看被索引的字段:
   select * from user_ind_columns where index_name=upper('&index_name');

128、查看索引的大小:
   select sum(bytes)/(1024*1024) as "size(M)" from user_segments where segment_name=upper('&index_name');

129、查看序列号发生器(last_number是当前值):
   select * from user_sequences ;

130、查看某表的约束条件:
   select constraint_name,constraint_type,search_condition,r_condition_name from user_constraints where table_name=upper('&table_name');

131、查看函数、过程的状态:
   select object_name,status from user_object where object_type='FUNCTION';
   select object_name,status from user_object where object_type='PROCEDRUE';

132、查找ORACLE的字符集(sys权限):
   select * from sys.props$ where name='NLS_CHARACTERSET';

133、ORACLE字符集不匹配会导致整个营业程序中凡是用到数据库中数据带有汉字的地方的时候,显示大量的“?????”字符,要改变终端的字符集,需要从注册表中找出所有的“NLS_LANG”,并把其字符串改为与ORACLE数据库中对应的字符集相匹配的字符串。若是数据库是ENGLISH字符串,则NLS_LANG对应的值为“AMERICAN_AMERICA.WE8ISO8859P1”。

134、在PL/SQL语句中,几个小知识点:
   substr(sting,m,n)中参数的含义:
           string:要从中取值的字符串;
           m:从字符串中第m个字母开始取值;
           n:从第m个字母开始取值直到第m+n-1个值(即取n个值);
用to_date()函数格式化显示的日期格式,如下:
(1)    yyyy-mm-dd hh24:mi:ss
(2)    MM-DD-YYYY
(3)    January 15, 1989, 11:00 A.M.
(4)    Month dd, YYYY, HH:MI A.M.

135、查看oracle中的数据文件:
   select * from sys.dba_data_files;

136、刷新oracle数据库中的共享池,使碎片小块内存合并为大块的内存,语句实现如下:
   alter system flush shared_pool;
在执行上述语句时,会造成系统性能暂时尖峰,因为对象都要重新加载,所以应该在数据库的负载不是很大的情况下进行。

137、    offiline 一个表空间:
Alter tablespace tablespace_name offline normal;

138、    SLQ/PLUS中修改用户的密码:
alter user user_name identified by new_password;

139、    Oralce 中的 group by 子句:
Use the GROUP BY clause to group selected rows and return a single row of summary information. Oracle collects each group of rows based on the values of the expression(s) specified in the GROUP BY clause.

140、    查看oracle数据库的背景进程(v$bgprocess)
select * from v$bgprocess;

141、    查看用户对某一个表的权限(sys.dba_tab_privs):
select * from sys.dba_tab_privs where grantee='用户名' and table_name = '表名';

142、    unix下mail命令的用法:
#mail
?n 2                (读取第二封信)
?n 4                (读取第四封信)
?+                    (读取下一封信)
?-                    (读取上一封信)

143、创建同义词:
CREATE [public] SYNONYM 同义词名称 FOR 用户名.表名@数据库连接名;
Drop any synonym;删除所有的同义词
Drop synonym synonym_name ;
查看同义词:
select synonym_name from user_synonyms;

144、若Oracle OPS中的一个down掉,最好OPS服务器的各个节点的数据库同时重新启动:
   Shutdown abort;
startup;

145、创建视图:
create view view_name as select col1,[[col2],…] from 用户名.表名@数据库连接名;
删除视图:
drop view view_name;
删除任何视图:
drop any view;
查看视图:
select view_name from user_views;

146、    建触发器:
create or replace trigger trigger_name
before/after update or delete or insert on tab_name
begin
   ……
end;

147、    用DBMS_OUTPUT输出使,若要在SQL/PLUS中显示出来,需要先执行如下语句:
SET SERVEROUTPUT ON;

148、SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。
  1) 数据查询语言DQL
  数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE
子句组成的查询块:
    SELECT   <字段名表>
    FROM   <表或视图名>
    WHERE   <查询条件>

  2 )数据操纵语言DML
  数据操纵语言DML主要有三种形式:
    (1) 插入:INSERT
    (2) 更新:UPDATE
    (3) 删除:DELETE

  3 )数据定义语言DDL
  数据定义语言DDL用来创建数据库中的各种对象-----表、视图、
索引、同义词、聚簇等如:
    CREATE TABLE/VIEW/INDEX/SYNONYM/CLUSTER
          |   |     |     |       |
          表 视图   索引   同义词     簇

  4 )数据控制语言DCL
  数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制
数据库操纵事务发生的时间及效果,对数据库实行监视等。如:
    (1) GRANT:授权。
    (2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。
    回滚---ROLLBACK
    回滚命令使数据库状态回到上次最后提交的状态。其格式为:
    SQL>ROLLBACK;
    (3) COMMIT [WORK]:提交。
    在数据库的插入、删除和修改操作时,只有当事务在提交到数据
库时才算完成。在事务提交前,只有操作数据库的这个人才能有权看
到所做的事情,别人只有在最后提交完成后才可以看到。
    提交数据有三种类型:显式提交、隐式提交及自动提交。下面分
别说明这三种类型。
  (1) 显式提交
  用COMMIT命令直接完成的提交为显式提交。其格式为:
    SQL>COMMIT;
  (2) 隐式提交
  用SQL命令间接完成的提交为隐式提交。这些命令是:
  ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,
EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
  (3) 自动提交
  若把AUTOCOMMIT设置为ON,则在插入、修改、删除语句执行后,
系统将自动进行提交,这就是自动提交。其格式为:
SQL>SET AUTOCOMMIT ON;

149、ORACLE用户连接的管理
用系统管理员,查看当前数据库有几个用户连接:
SQL> select username,sid,serial# from v$session;
如果要停某个连接用
SQL> alter system kill session 'sid,serial#';
如果这命令不行,找它UNIX的进程数
SQL>select pro.spid from v$session ses,v$process pro where ses.sid=21 and ses.paddr=pro.addr;
说明:21是某个连接的sid数
然后用 kill 命令杀此进程号。

150、ORACLE逻辑备份的SH文件
1)完全备份的SH文件:exp_comp.sh
rq=’date +"%m%d"’
su - oracle -c "exp system/manager full=y inctype=complete file=/oracle/export /db_comp$rq.dmp"
2)累计备份的SH文件:exp_cumu.sh
rq=’date +"%m%d"’
su - oracle -c "exp system/manager full=y inctype=cumulative file=/oracle/export /db_cumu$rq.dmp"
3)增量备份的SH文件: exp_incr.sh
rq=’date +"%m%d"’
su - oracle -c "exp system/manager full=y inctype=incremental file=/oracle/export /db_incr$rq.dmp"

151、改数据库的启动方式为archive归档方式:
1)先按正常方式关闭数据库,然后
    %svrmgrl
    SVRMGRL>connect internal
    SVRMGRL>startup mount [database_name];
    SVRMGRL>alter database [database_name] archivelog;
    SVRMGRL>archive log list;
    SVRMGRL>alter database open;

2)设置数据库开启后自动启动archive进程,改参数文件initoraid.ora中   
        log_archive_start=true
        log_archive_dest=directory or device name
        log_archive_format=filename format
再重新启动数据库,即可

3)注意事项
有足够的资源存放归档日志文件
定一个热备份计划,定期删除归档日志文件

152、ORACLE的分布式管理
  物理上存放于网络的多个ORACLE数据库,逻辑上可以看成一个单个的大数据库。用户可以通过网络对异地数据库中的数据同时进行存取,而服务器之间的协同处理对于工作站用户及应用程序而言是完全透明的:开发人员无需关心网络的链接细节、无需关心数据在网络接点中的具体分布情况、也无需关心服务器之间的协调工作过程。
  数据库之间的链接建立在DATABASE LINK上。要创建一个DB LINK,必须先在每个数据库服务器上设置链接字符串。例如Oracle中的tnsnames.ora中有以下一条和北京的数据库链接tobeijing:
链接字符串的设置                 说   明
tobeijing=(description=         database link名称:tobeijing
(address=(protocol=tcp)         采用tcp/ip协议
(host=www.bj.col.com.cn)       欲链接主机名称或IP地址
(port=1521))               网络端口1521
(connect_data=(sid=oracle7)))     安装ORACLE采用的sid

然后进入系统管理员SQL>操作符下,运行命令:
SQL>create public database link beijing connect to scott identified by tiger using 'tobeijing';
则创建了一个以scott用户和北京数据库的链接beijing,我们查询北京的scott数据:
SQL>select * from emp@beijing;
这样就可以把深圳和北京scott用户的数据做成一个整体来处理。
为了使有关分布式操作更透明,ORACLE数据库里有同义词的对象synonym
SQL>create synonym bjscottemp for emp@beijing;
于是就可以用bjscottemp来替代带@符号的分布式链接操作emp@beijing。
查看所有的数据库链接,进入系统管理员SQL>操作符下,运行命令:
SQL>select owner,object_name from dba_objects where object_type='DATABASE LINK';
建ORACLE快照日志:
SQL>create snapshot log on table3 with primary key;
建快照:
SQL>create snapshot table3beijing refresh force start with sysdate next sysdate+1/24 with primary key as select * from table3@beijing;
ORACLE的快照刷新方式refresh有三种:
fast 快速刷新,用snapshot log,只更新时间段变动部分
complete 完全刷新,运行SQL语句
force 自动判断刷新,介于fast和complete之间

153、定期分析数据库对象的脚本
  ORACLE9以后如果你想用基于成本的优化器,需要定期(每周)对数据库里的表和索引做analyze分析。
  数据库参数文件initorasid.ora里默认的优化器    optimizer_mode = choose
  你要改成   
         optimizer_mode = first_rows    (OLTP系统)
         optimizer_mode = all_rows    (DSS 系统)
  下面是一个可以在UNIX环境自动生成分析表和索引的脚本analyze.sh
  (sys用户的密码password要根据情况修改。)
   su - oracle -c "sqlplus sys/password"<   set pages 9999
   set heading off
   set echo off
   set feedback off
   spool /oracle_backup/bin/analyze.sql;
   select
   'analyze table '||owner||'.'||table_name||' estimate statistics sample 5000 rows;'    from dba_tables    where owner not in ('SYS','SYSTEM','PERFSTAT');
   select
   'analyze index '||owner||'.'||index_name||' compute statistics;'
   from dba_indexes where owner not in ('SYS','SYSTEM','PERFSTAT');
   spool off;
   set echo on
   set feedback on
   spool /oracle_backup/log/analyze.log;
   @/oracle_backup/bin/analyze.sql
   spool off;
   exit;
  如果你经常变动的表和索引只属于某个特定的用户(如果是test)可以把上面的
  owner not in ('SYS','SYSTEM','PERFSTAT') 改成
  owner in ('TEST')           
  来进行定期的分析。
  注意事项:如果你使用的是默认的优化器(choose),一定不要定期使用上面那个analyze.sh脚本。因为这时优化器可能更倾向于全表扫描。如果统计分析资料不全,SQL运行时会对缺少统计资料的表进行数据采集。会大大降低SQL的执行速度。我们要用下面这个del_analyze.sh脚本定期删除可能产生的分析结果, 保证优化器按规则(rule)执行。
   su - oracle -c "sqlplus sys/password"<   set pagesize 9999;
   set linesize 120;
   set heading off;
   set echo off;
   set feedback off;
   spool /oracle_backup/bin/del_analyze.sql;
   select
   'analyze table '||owner||'.'||table_name||' delete statistics;'
   from dba_tables    where owner not in ('SYS','SYSTEM','PERFSTAT');
   select
   'analyze index '||owner||'.'||index_name||' delete statistics;'
   from dba_indexes where owner not in ('SYS','SYSTEM','PERFSTAT');
   spool off;
   set echo on;
   set feedback on;
   spool /oracle_backup/log/del_analyze.log;
   @/oracle_backup/bin/del_analyze.sql
   spool off;
   exit;

154、OLTP和DSS不同数据库设计
OLTP 数据库    DSS 数据库
OLTP=online transaction processing    DSS = data warehousing
联机事物处理    数据仓库
例如:飞机订票,网上交易,BBS等    例如:各种资源资料查询系统
大量的在线用户和DML操作    很少的DML操作
大量基于索引的查询    大量的全表扫描的查询
用B-tree,reverse key索引,定期索引重建    用bitmap索引
需要较多的小的回退段    需要较少的大的回退段
不要用分布式查询    用分布式查询
数据对象的存储参数pctfree=20 或者更高    数据对象的存储参数pctfree 0
共享程序代码和各种变量常量    字符变量和线索
启动多线索服务    使用大的数据块,
db_file_mutiblock_read_count
使用较大的日志文件    使用较小的日志文件
listener开多个响应端口    增加sort_area_size

155、在Oracle中实现数据库的复制
在Internet上运作数据库经常会有这样的需求:把遍布全国各城市相似的数据库应用统一起来,一个节点的数据改变不仅体现在本地,还反映到远端。复制技术给用户提供了一种快速访问共享数据的办法。
一、实现数据库复制的前提条件
1)数据库支持高级复制功能
您可以用system身份登录数据库,查看v$option视图,如果其中Advanced replication为TRUE,则支持高级复制功能;否则不支持。
2)数据库初始化参数要求
①db_domain = test.com.cn
指明数据库的域名(默认的是WORLD),这里可以用您公司的域名。
②global_names = true
它要求数据库链接(database link)和被连接的数据库名称一致。
现在全局数据库名:db_name+”.”+db_domain
③有跟数据库job执行有关的参数
job_queue_processes = 1
job_queue_interval = 60
distributed_transactions = 10
open_links = 4
第一行定义SNP进程的启动个数为n。系统缺省值为0,正常定义范围为0~36,根据任务的多少,可以配置不同的数值。
第二行定义系统每隔N秒唤醒该进程一次。系统缺省值为60秒,正常范围为1~3600秒。事实上,该进程执行完当前任务后,就进入睡眠状态,睡眠一段时间后,由系统的总控负责将其唤醒。
如果修改了以上这几个参数,需要重新启动数据库以使参数生效。
二、实现数据库同步复制的步骤
假设在Internet上我们有两个数据库:一个叫深圳(shenzhen),一个叫北京(beijing)。
具体配置见下表:
数据库名 shenzhen beijing
数据库域名 test.com.cn test.com.cn
数据库sid号 shenzhen beijing
Listener端口号 1521 1521
服务器ip地址 10.1.1.100 10.1.1.200
1)确认两台数据库之间可以互相访问,在tnsnames.ora里设置数据库连接字符串。
①例如:深圳这边的数据库连接字符串是以下的格式
beijing =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.1.200)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = beijing)
)
)
运行$tnsping beijing
出现以下提示符:
Attempting to contact (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.1.200)(PORT=1521))
OK(n毫秒)
表明深圳数据库可以访问北京数据库。
②在北京那边也同样配置,确认$tnsping shenzhen 是通的。
2)改数据库全局名称,建公共的数据库链接。
①用system身份登录shenzhen数据库
SQL>alter database rename global_name to shenzhen.test.com.cn;
用system身份登录beijing数据库:
SQL>alter database rename global_name to beijing.test.com.cn;
②用system身份登录shenzhen数据库
SQL>create public database link beijing.test.com.cn using 'beijing';
测试数据库全局名称和公共的数据库链接
SQL>select * from global_name@beijing.test.com.cn;
返回结果为beijing.test.com.cn就对了。
用system身份登录beijing数据库:
SQL>create public database link shenzhen.test.com.cn using 'shenzhen';
测试数据库全局名称和公共的数据库链接
SQL>select * from global_name@shenzhen.test.com.cn;
返回结果为shenzhen.test.com.cn就对了。
3)建立管理数据库复制的用户repadmin,并赋权。
①用system身份登录shenzhen数据库
SQL>create user repadmin identified by repadmin default tablespace users temporary tablespace temp;
SQL>execute dbms_defer_sys.register_propagator('repadmin');
SQL>grant execute any procedure to repadmin;
SQL>execute dbms_repcat_admin.grant_admin_any_repgroup('repadmin');
SQL>grant comment any table to repadmin;
SQL>grant lock any table to repadmin;
②同样用system身份登录beijing数据库,运行以上的命令,管理数据库复制的用户repadmin,并赋权。
说明:repadmin用户名和密码可以根据用户的需求自由命名。
4)在数据库复制的用户repadmin下创建私有的数据库链接。
①用repadmin身份登录shenzhen数据库
SQL>create database link beijing.test.com.cn connect to repadmin identified by repadmin;
测试这个私有的数据库链接:
SQL>select * from global_name@beijing.test.com.cn;
返回结果为beijing.test.com.cn就对了。
②用repadmin身份登录beijing数据库
SQL>create database link shenzhen.test.com.cn connect to repadmin identified by repadmin;
测试这个私有的数据库链接
SQL>select * from global_name@shenzhen.test.com.cn;
返回结果为shenzhen.test.com.cn就对了。
5)创建或选择实现数据库复制的用户和对象,给用户赋权,数据库对象必须有主关键字。
假设我们用ORACLE里举例用的scott用户,dept表。
①用internal身份登录shenzhen数据库,创建scott用户并赋权
SQL>create user scott identified by tiger default tablespace users temporary tablespace temp;
SQL>grant connect, resource to scott;
SQL>grant execute on sys.dbms_defer to scott;
②用scott身份登录shenzhen数据库,创建表dept
SQL>create table dept
(deptno number(2) primary key,
dname varchar2(14),
loc varchar2(13) );
③如果数据库对象没有主关键字,可以运行以下SQL命令添加:
SQL>alter table dept add (constraint dept_deptno_pk primary key (deptno));
④在shenzhen数据库scott用户下创建主关键字的序列号,范围避免和beijing的冲突。
SQL> create sequence dept_no increment by 1 start with 1 maxvalue 44 cycle nocache;
(说明:maxvalue 44可以根据应用程序及表结构主关键字定义的位数需要而定)
⑤在shenzhen数据库scott用户下插入初始化数据
SQL>insert into dept values (dept_no.nextval,'accounting','new york');
SQL>insert into dept values (dept_no.nextval,'research','dallas');
SQL>commit;
⑥在beijing数据库那边同样运行以上①,②,③
⑦在beijing数据库scott用户下创建主关键字的序列号,范围避免和shenzhen的冲突。
SQL> create sequence dept_no increment by 1 start with 45 maxvalue 99 cycle nocache;
⑧在beijing数据库scott用户下插入初始化数据
SQL>insert into dept values (dept_no.nextval,'sales','chicago');
SQL>insert into dept values (dept_no.nextval,'operations','boston');
SQL>commit;
6)创建要复制的组scott_mg,加入数据库对象,产生对象的复制支持
①用repadmin身份登录shenzhen数据库,创建主复制组scott_mg
SQL> execute dbms_repcat.create_master_repgroup('scott_mg');
说明:scott_mg组名可以根据用户的需求自由命名。
②在复制组scott_mg里加入数据库对象
SQL>execute dbms_repcat.create_master_repobject(sname=>'scott',oname=>'dept', type=>'table',use_existing_object=>true,gname=>'scott_mg');
参数说明:
sname 实现数据库复制的用户名称
oname 实现数据库复制的数据库对象名称
(表名长度在27个字节内,程序包名长度在24个字节内)
type 实现数据库复制的数据库对象类别
(支持的类别:表,索引,同义词,触发器,视图,过程,函数,程序包,程序包体)
use_existing_object true表示用主复制节点已经存在的数据库对象
gname 主复制组名
③对数据库对象产生复制支持
SQL>execute dbms_repcat.generate_replication_support('scott','dept','table');
(说明:产生支持scott用户下dept表复制的数据库触发器和程序包)
④确认复制的组和对象已经加入数据库的数据字典
SQL>select gname, master, status from dba_repgroup;
SQL>select * from dba_repobject;
7)创建主复制节点
①用repadmin身份登录shenzhen数据库,创建主复制节点
SQL>execute dbms_repcat.add_master_database
(gname=>'scott_mg',master=>'beijing.test.com.cn',use_existing_objects=>true, copy_rows=>false, propagation_mode => 'asynchronous');
参数说明:
gname 主复制组名
master 加入主复制节点的另一个数据库
use_existing_object true表示用主复制节点已经存在的数据库对象
copy_rows false表示第一次开始复制时不用和主复制节点保持一致
propagation_mode 异步地执行
②确认复制的任务队列已经加入数据库的数据字典
SQL>select * from user_jobs;
8)使同步组的状态由停顿(quiesced )改为正常(normal)
①用repadmin身份登录shenzhen数据库,运行以下命令
SQL> execute dbms_repcat.resume_master_activity('scott_mg',false);
②确认同步组的状态为正常(normal)
SQL> select gname, master, status from dba_repgroup;
③如果这个①命令不能使同步组的状态为正常(normal),可能有一些停顿的复制,运行以下命令再试试(建议在紧急的时候才用):
SQL> execute dbms_repcat.resume_master_activity('scott_mg',true);
9)创建复制数据库的时间表,我们假设用固定的时间表:10分钟复制一次。
①用repadmin身份登录shenzhen数据库,运行以下命令
SQL>begin
dbms_defer_sys.schedule_push (
destination => 'beijing.test.com.cn',
interval => 'sysdate + 10/1440',
next_date => sysdate);
end;
?
SQL>begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 10/1440',
delay_seconds => 0,
rollback_segment => '');
end;
?
②用repadmin身份登录beijing数据库,运行以下命令
SQL>begin
dbms_defer_sys.schedule_push (
destination => ' shenzhen.test.com.cn ',
interval => 'sysdate + 10 / 1440',
next_date => sysdate);
end;
?
SQL>begin
dbms_defer_sys.schedule_purge (
next_date => sysdate,
interval => 'sysdate + 10/1440',
delay_seconds => 0,
rollback_segment => '');
end;

10)添加或修改两边数据库的记录,跟踪复制过程
如果你想立刻看到添加或修改后数据库的记录的变化,可以在两边repadmin用户下找到push的job_number,然后运行:
SQL>exec dbms_job.run(job_number);
三、异常情况的处理
1)检查复制工作正常否,可以在repadmin 用户下查询user_jobs
SQL>select job,this_date,next_date,what, broken from user_jobs;
正常的状态有两种:
任务闲——this_date为空,next_date为当前时间后的一个时间值
任务忙——this_date不为空,next_date为当前时间后的一个时间值
异常状态也有两种:
任务死锁——next_date为当前时间前的一个时间值
任务死锁——next_date为非常大的一个时间值,例如:4001-01-01
这可能因为网络中断照成的死锁
解除死锁的办法:
$ps –ef|grep orale
找到死锁的刷新快照的进程号ora_snp*,用kill –9 命令删除此进程
然后进入repadmin 用户SQL>操作符下,运行命令:
SQL>exec dbms_job.run(job_number);
说明:job_number 为用select job,this_date,next_date,what from user_jobs;命令查出的job编号。
2)增加或减少复制组的复制对象
①停止主数据库节点的复制动作,使同步组的状态由正常(normal)改为停顿(quiesced )
用repadmin身份登录shenzhen数据库,运行以下命令
SQL>execute dbms_repcat.suspend_master_activity (gname => 'scott_mg');
②在复制组scott_mg里加入数据库对象,保证数据库对象必须有主关键字。
SQL>execute dbms_repcat.create_master_repobject(sname=>'scott',oname=>'emp', type=>'table',use_existing_object=>true,gname=>'scott_mg');
对加入的数据库对象产生复制支持
SQL>execute dbms_repcat.generate_replication_support('scott','emp','table');
③在复制组scott_mg里删除数据库对象。
SQL>execute dbms_repcat.drop_master_repobject ('scott','dept','table');
④重新使同步组的状态由停顿(quiesced )改为正常(normal)。
SQL> execute dbms_repcat.resume_master_activity('scott_mg',false);

156、较好的重新启动数据库的步骤   
   因为各种各样的原因,有时候工作数据库需要重新启动.
   我列出一个较好的操作步骤,希望对初学者有些帮助.
   1)停应用层的各种程序.
   2)停oralce的监听进程:
      $lsnrctl stop
   3)在独占的系统用户下,备份控制文件:
      SQL>alter database backup controlfile to trace;
   4)在独占的系统用户下,手工切换重作日志文件,确保当前已修改过的数据存入文件:
      SQL>alter system switch logfile;
   5)在独占的系统用户下,运行下面SQL语句,生成杀数据库用户连接的kill_all_session.sql文件:
      set head off;
      set feedback off;
      set newpage none;
      spool /oracle_backup/bin/kill_all_session.sql
      select 'alter system kill session '''||sid||','||serial#||''';' from v$session where username is not null;
      spool off;
   6)在独占的系统用户下,执行杀数据库用户连接的kill_all_session.sql文件
      SQL>@/oracle_backup/bin/kill_all_session.sql
   7)在独占的系统用户下,用immediate方式关闭数据库:
      SQL>shutdown immediate;   
      或者
      SVRMGRL>shutdown immediate;   
   8)启动oralce的监听进程
      $lsnrctl start   
   9)进入独占的系统用户下,启动oralce数据库   
      $sqlplus /nolog
      SQL>connect / as sysdba
      SQL>startup;   
      或者
      $svrmgrl
      SVRMGRL>connect internal;
      SVRMGRL>startup;       
     10)启动应用层的各种程序.       

157、导出创建非唯一索引脚本的方法
  在ORACLE里用逻辑备份工具exp导出数据时,如果使用默认参数, 会把创建索引的语句一起导出来。当数据和索引小的时候,我们可能不太会计较导入时间; 如果数据和索引大的时候,就应该考虑导入时间的问题了。如果在导出时选择 indexes=n 的参数, 索引类型是非唯一(nounique)要根据ORACLE数据字典dba_indexes和dba_ind_columns里的信息生成创建索引的脚本。在导入完成后再根据需要运行这些创建索引的脚本。
  dba_indexes里记录了索引类型和存储参数等信息。
  dba_ind_columns里记录了索引的字段信息, 它的结构如下: 
SQL> desc dba_ind_columns;
name                       null?   type
----------------------------------------- -------- -------------------------
index_owner                   not null    varchar2(30)
index_name                   not null    varchar2(30)
table_owner                   not null    varchar2(30)
table_name                   not null    varchar2(30)
column_name                              varchar2(4000)
column_position                 not null    number
column_length                 not null    number
descend                              varchar2(4)
column_name记录着有索引的字段, column_position标记着字段在创建索引时的位置, descend指索引的排序, 有asc和desc两种,而desc排序方法用的较少,本文只考虑asc的情况。
步骤一:先创建一个视图index_nouniq_column_num列出非系统用户nonunique索引的用户名, 索引名和字段数量。
SQL> create view index_nouniq_column_num as select t1.owner,t1.index_name,count(0) as column_num    from dba_indexes t1,dba_ind_columns t2 where
t1.uniqueness='NONUNIQUE'    and instr(t1.owner,'sys')=0 and
t1.owner=t2.index_owner and t1.index_name=t2.index_name
group by t1.owner,t1.index_name order by t1.owner,column_num;
  步骤二:为了处理方便,建一个索引字段临时表index_columns, 它的column_names记录了以逗号分隔,顺序排列的索引字段。
SQL> create table index_columns(
   index_owner     varchar2(30)    not null,
   index_name   varchar2(30)    not null,
   column_names varchar2(512)    not null)
   tablespace users;
  步骤三:把只有一个字段的索引内容插入索引字段临时表index_columns。
SQL> insert into index_columns select t1.owner,t1.index_name,t2.column_name from
   index_nouniq_column_num t1,dba_ind_columns t2
   where t1.column_num=1 and t1.owner=t2.index_owner and
t1.index_name=t2.index_name
   order by t1.owner,t1.index_name;
SQL> commit;
  步骤四:把多个字段的索引内容插入索引字段临时表index_columns。用到以下一个函数getcloumns和过程select_index_columns。函数getcloumns:
create or replace function getcloumns(
   index_owner1    in varchar2,
   index_name1      in varchar2,
   column_nums1    in number) return varchar2
is
  all_columns    varchar2(512);
  total_num        number;
i            number;
cursor c1 is select column_name from dba_ind_columns where index_owner=index_owner1 and
index_name=index_name1 order by column_position;
  dummy c1%rowtype;
begin
  total_num:=column_nums1;
  open c1;
  fetch c1 into   dummy;
  i:=0;
  while c1%found loop
     i:=i+1;
     if (i=total_num) then
         all_columns:= all_columns||dummy.column_name;
     else
         all_columns:= all_columns||dummy.column_name||',';
     end if;
     fetch c1 into dummy;
  end loop;
  close c1;
  return all_columns;
exception
  when no_data_found then
      return all_columns;
end;
/

过程select_index_columns:
create or replace procedure select_index_columns
is
  all_columns    varchar2(2000);
  cursor c1 is select * from index_nouniq_column_num where column_num>=2;
  dummy c1%rowtype;
begin
  open c1;
  fetch c1 into   dummy;
  while c1%found loop
       select getcloumns(dummy.owner,dummy.index_name,dummy.column_num) into all_columns from dual;
     insert into index_columns values(dummy.owner,dummy.index_name,all_columns);
     fetch c1 into dummy;
  end loop;
  commit;
  close c1;
exception
  when others then
     rollback;
end;
/

SQL> exec select_index_columns;
  执行select_index_columns过程就可以把多个字段的索引内容插入索引字段临时表了。
  步骤五:最后运行create_now_index.sql,根据索引字段临时表index_columns和dba_indexes在路径/oracle_backup/log
下生成创建非唯一索引脚本create_index.sql。

create_now_index.sql内容:

set heading off;
set pagesize 5000;
truncate table index_columns;
-- 把多个字段的索引内容插入索引字段临时表
exec select_index_columns;
-- 把只有一个字段的索引内容插入索引字段临时表
insert into index_columns select t1.owner,t1.index_name,t2.column_name
from index_nouniq_column_num t1,dba_ind_columns t2
where t1.column_num=1 and t1.owner=t2.index_owner and t1.index_name=t2.index_name
order by t1.owner,t1.index_name;
commit;
spool /oracle_backup/log/create_index.sql;
SELECT 'CREATE INDEX '||t1.owner||'.'||t1.index_name|| chr(10) ||' ON '||t1.table_name||    ' ('||column_names||')'|| chr(10) ||' TABLESPACE '||t1.tablespace_name|| chr(10) ||    ' PCTFREE '||t1.pct_free || chr(10) ||' STORAGE (INITIAL '||t1.initial_extent||    ' NEXT '||t1.next_extent||' PCTINCREASE '||t1.pct_increase||');'|| chr(10) || chr(10)
FROM dba_indexes t1,index_columns t2
WHERE t1.owner=t2.index_owner and t1.index_name=t2.index_name
ORDER BY t1.owner, t1.table_name;
spool off;

158、ORACLE 常用的SQL语法和数据对象
一.数据控制语句 (DML) 部分
1)INSERT (往数据表里插入记录的语句)
INSERT INTO 表名(字段名1, 字段名2, ……) VALUES ( 值1, 值2, ……);
INSERT INTO 表名(字段名1, 字段名2, ……) SELECT (字段名1, 字段名2, ……) FROM 另外的表名;
字符串类型的字段值必须用单引号括起来, 例如: ’GOOD DAY’
如果字段值里包含单引号’ 需要进行字符串转换, 我们把它替换成两个单引号''.
字符串类型的字段值超过定义的长度会出错, 最好在插入前进行长度校验.
日期字段的字段值可以用当前数据库的系统时间SYSDATE, 精确到秒
或者用字符串转换成日期型函数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’)
TO_DATE()还有很多种日期格式, 可以参看ORACLE DOC.
年-月-日 小时:分钟:秒 的格式YYYY-MM-DD HH24:MI:SS
INSERT时最大可操作的字符串长度小于等于4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型,
方法借用ORACLE里自带的DBMS_LOB程序包.
INSERT时如果要用到从1开始自动增长的序列号, 应该先建立一个序列号
CREATE SEQUENCE 序列号的名称 (最好是表名+序列号标记) INCREMENT BY 1 START WITH 1
MAXVALUE 99999 CYCLE NOCACHE;
其中最大的值按字段的长度来定, 如果定义的自动增长的序列号 NUMBER(6) , 最大值为999999,INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL
2)DELETE (删除数据表里记录的语句)
DELETE FROM表名 WHERE 条件;
注意:删除记录并不能释放ORACLE里被占用的数据块表空间. 它只把那些被删除的数据块标成unused.如果确实要删除一个大表里的全部记录, 可以用 TRUNCATE 命令, 它可以释放占用的数据块表空间:
TRUNCATE TABLE 表名;
此操作不可回退.
3)UPDATE (修改数据表里记录的语句)
UPDATE表名 SET 字段名_1=值1, 字段名_2=值2, …… WHERE 条件;
如果修改的值N没有赋值或定义时, 将把原来的记录内容清为NULL, 最好在修改前进行非空校验; 值N超过定义的长度会出错, 最好在插入前进行长度校验..
注意事项:
A.    以上SQL语句对表都加上了行级锁,
   确认完成后, 必须加上事物处理结束的命令 COMMIT 才能正式生效,
   否则改变不一定写入数据库里.   
   如果想撤回这些操作, 可以用命令 ROLLBACK 复原.
B.    在运行INSERT, DELETE 和 UPDATE 语句前最好估算一下可能操作的记录范围, 应该把它限定在较小 (一万条记录) 范围内,. 否则ORACLE处理这个事物用到很大的回退段。
   程序响应慢甚至失去响应. 如果记录数上十万以上这些操作, 可以把这些SQL语句分段分次完成, 其间加上COMMIT 确认事物处理.
二.数据定义 (DDL) 部分
1)CREATE (创建表, 索引, 视图, 同义词, 过程, 函数, 数据库链接等)
ORACLE常用的字段类型有
CHAR            固定长度的字符串
VARCHAR2        可变长度的字符串
NUMBER(M,N)        数字型M是位数总长度, N是小数的长度
DATE            日期类型
创建表时要把较小的不为空的字段放在前面, 可能为空的字段放在后面
创建表时可以用中文的字段名, 但最好还是用英文的字段名
创建表时可以给字段加上默认值, 例如 DEFAULT SYSDATE
这样每次插入和修改时, 不用程序操作这个字段都能得到动作的时间
创建表时可以给字段加上约束条件
例如 不允许重复 UNIQUE, 关键字 PRIMARY KEY
2)ALTER (改变表, 索引, 视图等)
改变表的名称
ALTER TABLE 表名1 TO 表名2;
在表的后面增加一个字段
ALTER TABLE表名 ADD 字段名 字段名描述;
修改表里字段的定义描述
ALTER TABLE表名 MODIFY字段名 字段名描述;
给表里的字段加上约束条件
ALTER TABLE 表名 ADD CONSTRAINT 约束名 PRIMARY KEY (字段名);
ALTER TABLE 表名 ADD CONSTRAINT 约束名 UNIQUE (字段名);
把表放在或取出数据库的内存区
ALTER TABLE 表名 CACHE;
ALTER TABLE 表名 NOCACHE;
3)DROP    (删除表, 索引, 视图, 同义词, 过程, 函数, 数据库链接等)
删除表和它所有的约束条件
DROP TABLE 表名 CASCADE CONSTRAINTS;
4)TRUNCATE (清空表里的所有记录, 保留表的结构)
TRUNCATE 表名;
三.查询语句 (SELECT) 部分
SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE 条件;
字段名可以带入函数
例如: COUNT(*), MIN(字段名), MAX(字段名), AVG(字段名), DISTINCT(字段名),
      TO_CHAR(DATE字段名,'YYYY-MM-DD HH24:MI:SS')
NVL(EXPR1, EXPR2)函数
解释:   
IF EXPR1=NULL
       RETURN EXPR2
ELSE
           RETURN EXPR1
DECODE(AA﹐V1﹐R1﹐V2﹐R2....)函数
解释:
IF AA=V1 THEN RETURN R1
IF AA=V2 THEN RETURN R2
..…
ELSE
RETURN NULL
LPAD(char1,n,char2)函数
解释:
字符char1按制定的位数n显示,不足的位数用char2字符串替换左边的空位
字段名之间可以进行算术运算
例如: (字段名1*字段名1)/3
查询语句可以嵌套
例如: SELECT …… FROM
(SELECT …… FROM表名1, [表名2, ……] WHERE 条件) WHERE 条件2;
两个查询语句的结果可以做集合操作
例如: 并集UNION(去掉重复记录), 并集UNION ALL(不去掉重复记录), 差集MINUS, 交集INTERSECT
分组查询
SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] GROUP BY字段名1
[HAVING 条件] ;
两个以上表之间的连接查询
SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE
       表名1.字段名 = 表名2. 字段名 [ AND ……] ;
SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE
       表名1.字段名 = 表名2. 字段名(+) [ AND ……] ;
有(+)号的字段位置自动补空值
查询结果集的排序操作, 默认的排序是升序ASC, 降序是DESC
SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……]
ORDER BY字段名1, 字段名2 DESC;
字符串模糊比较的方法
INSTR(字段名, ‘字符串’)>0   
字段名 LIKE ‘字符串%’ [‘%字符串%’]
每个表都有一个隐含的字段ROWID, 它标记着记录的唯一性.
四.ORACLE里常用的数据对象 (SCHEMA)
1)索引 (INDEX)
CREATE INDEX 索引名ON 表名 ( 字段1, [字段2, ……] );
ALTER INDEX 索引名 REBUILD;
一个表的索引最好不要超过三个 (特殊的大表除外), 最好用单字段索引, 结合SQL语句的分析执行情况,
也可以建立多字段的组合索引和基于函数的索引
ORACLE8.1.7字符串可以索引的最大长度为1578 单字节
ORACLE8.0.6字符串可以索引的最大长度为758 单字节
2)视图 (VIEW)
CREATE VIEW 视图名AS SELECT …. FROM …..;
ALTER VIEW视图名 COMPILE;
视图仅是一个SQL查询语句, 它可以把表之间复杂的关系简洁化.
3)同义词 (SYNONMY)
CREATE SYNONYM同义词名FOR 表名;
CREATE SYNONYM同义词名FOR 表名@数据库链接名;
4)数据库链接 (DATABASE LINK)
CREATE DATABASE LINK数据库链接名CONNECT TO 用户名 IDENTIFIED BY 密码 USING ‘数据库连接字符串’;
数据库连接字符串可以用NET8 EASY CONFIG或者直接修改TNSNAMES.ORA里定义.
数据库参数global_name=true时要求数据库链接名称跟远端数据库名称一样
数据库全局名称可以用以下命令查出
SELECT * FROM GLOBAL_NAME;
查询远端数据库里的表
SELECT …… FROM 表名@数据库链接名;
五.权限管理 (DCL) 语句
1)GRANT    赋于权限
常用的系统权限集合有以下三个:
CONNECT(基本的连接), RESOURCE(程序开发), DBA(数据库管理)
常用的数据对象权限有以下五个:
ALL    ON 数据对象名,    SELECT ON 数据对象名,    UPDATE ON 数据对象名,
DELETE    ON 数据对象名, INSERT ON 数据对象名,   ALTER ON 数据对象名
GRANT CONNECT, RESOURCE TO 用户名;
GRANT SELECT ON 表名 TO 用户名;
GRANT SELECT, INSERT, DELETE ON表名 TO 用户名1, 用户名2;
2)REVOKE 回收权限
REVOKE CONNECT, RESOURCE FROM 用户名;
REVOKE SELECT ON 表名 FROM 用户名;
REVOKE SELECT, INSERT, DELETE ON表名 FROM 用户名1, 用户名2;

159、ORACLE锁的管理
ORACLE里锁有以下几种模式:
   0:none
   1:null     空                               
   2:Row-S   行共享(RS):共享表锁
   3:Row-X   行专用(RX):用于行的修改
   4:Share   共享锁(S):阻止其他DML操作
   5:S/Row-X   共享行专用(SRX):阻止其他事务操作
   6:exclusive 专用(X):独立访问使用
数字越大锁级别越高, 影响的操作越多。
   一般的查询语句如select ... from ... ;是小于2的锁, 有时会在v$locked_object出现。select ... from ... for update; 是2的锁。
   当对话使用for update子串打开一个游标时,所有返回集中的数据行都将处于行级(Row-X)独占式锁定,其他对象只能查询这些数据行,不能进行update、delete或select...for update操作。insert/update/delete ... ;     是3的锁。   
   没有commit之前插入同样的一条记录会没有反应, 因为后一个3的锁会一直等待上一个3的锁, 我们必须释放掉上一个才能继续工作。
   创建索引的时候也会产生3,4级别的锁。
   locked_mode为2,3,4不影响DML(insert,delete,update,select)操作,
   但DDL(alter,drop等)操作会提示ora-00054错误。
   有主外键约束时 update / delete ... ; 可能会产生4,5的锁。
   DDL语句时是6的锁。
   以DBA角色, 查看当前数据库里锁的情况可以用如下SQL语句:
   select object_id,session_id,locked_mode from v$locked_object;
   select t2.username,t2.sid,t2.serial#,t2.logon_time
   from v$locked_object t1,v$session t2
   where t1.session_id=t2.sid order by t2.logon_time;
   如果有长期出现的一列,可能是没有释放的锁。
   我们可以用下面SQL语句杀掉长期没有释放非正常的锁:
   alter system kill session 'sid,serial#';
   如果出现了锁的问题, 某个DML操作可能等待很久没有反应。当你采用的是直接连接数据库的方式,不要用OS系统命令 $kill process_num 或者 $kill -9 process_num来终止用户连接,因为一个用户进程可能产生一个以上的锁, 杀OS进程并不能彻底清除锁的问题。
   记得在数据库级别用alter system kill session 'sid,serial#';杀掉不正常的锁。

160、使用特殊索引的注意事项
   在ORACLE里除了我们常用的B树索引外,还有一些特殊索引能被使用。如:倒序索引,位映射索引,函数索引等。我根据自己的体会,列一个注意事项:
1)倒序索引:
  ORACLE DOC上说倒序索引比较适合于序列号产生的字段,如唯一编号。 但是这样的索引对于范围的比较,如 > < between ... and ... 等操作是不起作用的;只对 = in 等操作才会调用索引。
   所以一般的自动增长的PK字段还是用常规B树索引好一些。
2)位映射索引:
   适合于唯一记录数较少,DML操作较少的字段。如历史数据表里的类别字段。它可以减少索引存储空间的占用,并提高访问速度。
   最好在查询时加提示/*+ first_rows */ 或者 /*+ index(表名 索引名)*/ 确认使用位映射索引。
3)函数索引:
   需要修改数据库里面两个动态参数:
   QUERY_REWRITE_ENABLED=TRUE
   QUERY_REWRITE_INTEGRITY=TRUSTED
   函数索引才会在有提示/*+ first_rows */ 或者 /*+ index(表名 索引名)*/ 时被使用。

161、快速转移数据的方法
  如果你要把ORACLE里的大量数据(80M以上)转移到另外的用户,另外的表空间里。可以用下面介绍的快速转移数据的方法。
  一、建新表的方式
  create table target_tablename tablespace target_tablespace_name nologging
  pctfree 10 pctused 60
  storage(initial 5M next 5M minextents 1 maxextents unlimited pctincrease 0)
  as select * from username.source_tablename where 条件;
  注意事项:    新建的表没有原来表的索引和默认值,
         只有非空(not null)的约束素条件可以继承过来,
         其它的约束条件或索引需要重新建立.
  二、直接插入的方法
  INSERT /*+ APPEND */ INTO target_tablename
     SELECT * FROM username.source_tablename where 条件;
  COMMIT;                 
  注意事项:
     用INSERT /*+ APPEND */ 的方法会对target_tablename产生级别为6的独占锁,
     如果运行此命令时还有对target_tablename的DML操作会排队在它后面,
     对OLTP系统在用的表操作是不合适的。
  说明:这两种方法转移数据时没有用SGA里数据缓冲区和事物处理的回滚段, 也不写联机事物日志,就象数据库装载工具SQLLOAD一样直接把数据写到物理文件,速度是很快的。

162、创建和使用分区的表
  在ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能。以system身份登陆数据库,查看 v$option视图,如果其中Partition为TRUE,则支持分区功能;否则不支持。Partition有基于范围、哈希、综和三种类型。我们用的比较多的是按范围分区的表。我们以一个2001年开始使用的留言版做例子讲述分区表的创建和使用:
1)    以system 身份创建独立的表空间(大小可以根据数据量的多少而定)
create tablespace g_2000q4 datafile '/home/oradata/oradata/test/g_2000q4.dbf' size 50M default storage (initial 100k next 100k minextents 1 maxextents unlimited pctincrease 1);
   create tablespace g_2001q1 datafile '/home/oradata/oradata/test/g_2001q1.dbf' size 50M default storage (initial 100k next 100k minextents 1 maxextents unlimited pctincrease 1);
   create tablespace g_2001q2 datafile '/home/oradata/oradata/test/g_2001q2.dbf' size 50M default storage (initial 100k next 100k minextents 1 maxextents unlimited pctincrease 1);
   2)用EXPORT工具把旧数据备份在guestbook.dmp中,把原来的guestbook表改名
      alter table guestbook rename to guestbookold;
   以guestbook 身份创建分区的表
   create table guestbook(
       id             number(16) primary key,
       username        varchar2(64),
       sex             varchar2(2),
       email           varchar2(256),
       expression       varchar2(128),
       content           varchar2(4000),
       time           date,
       ip             varchar2(64)
   )
partition by range (time)
(partition g_2000q4 values less than (to_date('2001-01-01','yyyy-mm-dd'))
tablespace g_2000q4
storage(initial 100k next 100k minextents 1 maxextents unlimited pctincrease 0),
partition g_2001q1 values less than (to_date('2001-04-01','yyyy-mm-dd'))
tablespace g_2001q1
storage(initial 100k next 100k minextents 1 maxextents unlimited pctincrease 0),
partition g_2001q2 values less than (to_date('2001-07-01','yyyy-mm-dd'))
tablespace g_2001q2
storage(initial 100k next 100k minextents 1 maxextents unlimited pctincrease 0)
);
(说明:分区的名称可以和表空间的名称不一致。这里是每个季度做一个分区,当然也可以每个月做一个分区)
3)IMPORT导入数据,参数ignore=y
4)分区表的扩容:
到了2001 年下半年,建立新的表空间:
create tablespace g_2001q3 datafile '/home/oradata/oradata/test/g_2001q3.dbf' size 50m default storage (initial 100k next 100k minextents 1 maxextents unlimited pctincrease 1);
为表添加新分区和表空间:
alter table guestbook add partition g_2001q3 values less than
(to_date('2001-10-01','yyyy-mm-dd')
tablespace g_2001q3
storage(initial 100k next 100k minextents 1 maxextents unlimited pctincrease 0);
5)删除不必要的分区
将2000年的数据备份(备份方法见 6、EXPORT 分区),将2000年的分区删除。
alter table guestbook drop partion g_2000q4;
删除物理文件
%rm /home/oradata/oradata/test/g_2000q4.dbf
6)EXPORT 分区:
% exp guestbook/guestbook_password tables=guestbook:g_2000q4 rows=Y
file=g_2000q4.dmp
7)IMPORT分区:
例如在2001 年,用户要查看2000 年的数据,先创建表空间
create tablespace g_2000q4 datafile '/home/oradata/oradata/test/g_2000q4.dbf' size 50m default storage (initial 100k next 100k minextents 1 maxextents unlimited pctincrease 1);
为表添加新分区和表空间:
alter table guestbook add partition g_2000q4
values less than (to_date('2001-01-01','yyyy-mm-dd')
tablespace g_2001q3
storage(initial 100k next 100k minextents 1 maxextents unlimited pctincrease 0);
导入数据
%imp guestbook/guestbook_password file=g_2000q4.dmp tables=(guestbook:g_2000q4) ignore=y
(说明:如果不指明导入的分区,imp会自动按分区定义的范围装载数据

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/72973/viewspace-605657/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2009-04-20

  • 博文量
    18
  • 访问量
    44263