1. oracle自右而左进行解析,from子句中应该将最先需要被处理的表写在最右边,如果有3个以上的表连接查询,那就需要选择那个被其他表所引用的表放在最后;

  2. ORACLE采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之左,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的之右;

  3. select子句中避免使用*;

  4. truncate代替delete,因为delete时oracle会产生大量的日志;

  5. 多表连接时,多使用别名,字段的别名也是一样;

  6. 能用=的时候,不用like,like会降低查询速度;

  7. 能在where子句中处理的条件,尽量不要放到having子句中,因为oracle先处理where子句,后处理having子句;

  8. 大于等于的效率高于大于,比如大于等于3,oracle会直接定位到3,然后从3开始去后面的数据,但是大于2,会先定位到2,然后再取2之后第一个;

  9. 不在索引列进行运算,当索引列进行运算时,优化器不会使用索引,转而进行全表扫描;

  10. 当索引建立在多个字段时,where子句必须用到第一个索引字段才会走索引,不使用第一个列时走全表扫描;

  11. 避免在索引字段使用not进行判断,使用not时,oracle会进行全表扫描。

  12. 一般来说exists的效率高于in,in的效率高于or,所以能用exists的不用in,能用in的就不用or,IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。 我们要根据实际的情况做相应的优化,不能绝对的说谁的效率高谁的效率低,所有的事都是相对的;

  13. 如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。使用not in时,子查询返回的值不能包含空值,否则查询结果为空。

oracle常用

存储过程debug赋权

GRANT debug any procedure, debug connect session TO hsscm;

grant execute on hscon.f_run_rawdata_prepare to hsscm;

oracle中的hint优化详解

ORACLE 大数据insert可以使用下面hint来提高SQL的性能

insert /*+ append parallel(a, 4) nologging / into target_table a select /+ parallel(b, 4) */ * from source_table b;

APPEND的作用是在表的高水位上分配空间,不去寻找 freelist 中的free block , 直接在table HWM 上面加入数据; nologging 会大量减少日志; parallel 并行。

oracle中hint 详解

Hint概述

基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。

此时就需要DBA进行人为的干预,告诉优化器使用我们指定的存取路径或连接类型生成执行计划,从 而使语句高效的运行。例如,如果我们认为对于一个特定的语句,执行全表扫描要比执行索引扫描更有效,则我们就可以指示优化器使用全表扫描。在Oracle 中,是通过为语句添加 Hints(提示)来实现干预优化器优化的目的。 不建议在代码中使用hint,在代码使用hint使得CBO无法根据实际的数据状态选择正确的执行计划。毕竟 数据是不断变化的, 10g以后的CBO也越来越完善,大多数情况下我们该让Oracle自行决定采用什么执行计划。

Oracle Hints是一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。我们可以用Oracle Hints来实现: 1) 使用的优化器的类型 2) 基于代价的优化器的优化目标,是all_rows还是first_rows。 3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用rowid。 4) 表之间的连接类型 5) 表之间的连接顺序 6) 语句的并行程度

除了”RULE”提示外,一旦使用的别的提示,语句就会自动的改为使用CBO优化器,此时如果你的数据字典中没有统计数据,就会使用缺省的统计数据。所以建议大家如果使用CBO或Hints提示,则最好对表和索引进行定期的分析。

如何使用Hints:

Hints只应用在它们所在sql语句块(statement block,由select、update、delete关键字标识)上,对其它SQL语句或语句的其它部分没有影响。如:对于使用union操作的2个sql语句,如果只在一个sql语句上有Hints,则该Hints不会影响另一个sql语句。

我们可以使用注释(comment)来为一个语句添加Hints,一个语句块只能有一个注释,而且注释只能放在SELECT, UPDATE, or DELETE关键字的后面

使用Oracle Hints的语法:

{DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */

or

{DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...

注解:

  1. DELETE、INSERT、SELECT和UPDATE是标识一个语句块开始的关键字,包含提示的注释只能出现在这些关键字的后面,否则提示无效。

  2. “+”号表示该注释是一个Hints,该加号必须立即跟在”/*”的后面,中间不能有空格。

  3. hint是下面介绍的具体提示之一,如果包含多个提示,则每个提示之间需要用一个或多个空格隔开。

  4. text 是其它说明hint的注释性文本

  5. 使用表别名。如果在查询中指定了表别名,那么提示必须也使用表别名。例如:select /*+ index(e,dept_idx) */ * from emp e;

  6. 不要在提示中使用模式名称:如果在提示中指定了模式的所有者,那么提示将被忽略。例如: select /*+ index(scott.emp,dept_idx) */ * from emp

注意:如果你没有正确的指定Hints,Oracle将忽略该Hints,并且不会给出任何错误。

hint被忽略

如果CBO认为使用hint会导致错误的结果时,hint将被忽略,详见下例

SQL> select /*+ index(t t_ind) */ count(*) from t;`` ``Execution Plan`` ``----------------------------------------------------------`` ``Plan hash value: 2966233522`` ``-------------------------------------------------------------------`` ``| Id | Operation     | Name | Rows | Cost (%CPU)| Time   |`` ``-------------------------------------------------------------------`` ``|  0 | SELECT STATEMENT  |   |   1 |  57  (2)| 00:00:01 |`` ``|  1 | SORT AGGREGATE  |   |   1 |      |     |`` ``|  2 |  TABLE ACCESS FULL| T  | 50366 |  57  (2)| 00:00:01 |`` ``------------------------------------------------------------------- 

因为我们是对记录求总数,且我们并没有在建立索引时指定不能为空,如果CBO选择在索引上进行count时,但索引字段上的值为空时,结果将不准确,故CBO没有选择索引。

SQL> select /*+ index(t t_ind) */ count(id) from t;`` ``Execution Plan`` ``----------------------------------------------------------`` ``Plan hash value: 646498162`` ``--------------------------------------------------------------------------`` ``| Id | Operation    | Name | Rows | Bytes | Cost (%CPU)| Time   |`` ``--------------------------------------------------------------------------`` ``|  0 | SELECT STATEMENT |    |   1 |   5 |  285  (1)| 00:00:04 |`` ``|  1 | SORT AGGREGATE |    |   1 |   5 |      |     |`` ``|  2 |  INDEX FULL SCAN| T_IND | 50366 |  245K|  285  (1)| 00:00:04 |`` ``--------------------------------------------------------------------------

因为我们只对id进行count,这个动作相当于count索引上的所有id值,这个操作和对表上的id字段进行count是一样的(组函数会忽略null值),故使用了索引。

和优化器相关的hint

1、/*+ ALL_ROWS */ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.

SELECT /+ ALL+_ROWS/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

2、/*+ FIRST_ROWS(n) */ 表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.

SELECT /*+FIRST_ROWS(20) */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

3、/+ RULE/ 表明对语句块选择基于规则的优化方法.

SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';

和访问路径相关的hint

1、/+ FULL(TABLE)/ 表明对表选择全局扫描的方法.

SELECT /+FULL(A)/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';

2、/*+ INDEX(TABLE INDEX_NAME) */ 表明对表选择索引的扫描方法.

SELECT /*+INDEX(BSEMPMS SEX_INDEX) */ * FROM BSEMPMS WHERE SEX='M';

3、/+ INDEX_ASC(TABLE INDEX_NAME)/ 表明对表选择索引升序的扫描方法.

SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ * FROM BSEMPMS WHERE DPT_NO='SCOTT';

4、/+ INDEX_COMBINE/ 为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.

SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI) */ * FROM BSEMPMS WHERE SAL<5000000 AND HIREDATE

5、/*+ INDEX_JOIN(TABLE INDEX_NAME1 INDEX_NAME2) */ 当谓词中引用的列都有索引的时候,可以通过指定采用索引关联的方式,来访问数据

select /*+ index_join(t t_ind t_bm) */ id from t where id=100 and object_name='EMPLOYEES'

6、/+ INDEX_DESC(TABLE INDEX_NAME)/ 表明对表选择索引降序的扫描方法.

SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ * FROM BSEMPMS WHERE DPT_NO='SCOTT';

7、/*+ INDEX_FFS(TABLE INDEX_NAME) */ 对指定的表执行快速全索引扫描,而不是全表扫描的办法.

SELECT /* + INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';

8、/*+ INDEX_SS(T T_IND) */ 从9i开始,oracle引入了这种索引访问方式。当在一个联合索引中,某些谓词条件并不在联合索引的第一列时,可以通过Index Skip Scan来访问索引获得数据。当联合索引第一列的唯一值个数很少时,使用这种方式比全表扫描效率高。

 ``SQL> create table t as select 1 id,object_name from dba_objects;<``br``> Table created.<``br``> SQL> insert into t select 2,object_name from dba_objects;    <``br``> 50366 rows created.<``br``> SQL> insert into t select 3,object_name from dba_objects;    <``br``> 50366 rows created. <``br``> SQL> insert into t select 4,object_name from dba_objects;    <``br``> 50366 rows created. <``br``> SQL> commit;<``br``> Commit complete.<``br``> SQL> create index t_ind on t(id,object_name);<``br``> Index created.<``br``> SQL> exec dbms_stats.gather_table_stats('HR','T',cascade=>true);<``br``> PL/SQL procedure successfully completed.

执行全表扫描

SQL> select /*+ full(t) */ * from t where object_name='EMPLOYEES';``6 rows selected.``Execution Plan``----------------------------------------------------------``Plan hash value: 1601196873``--------------------------------------------------------------------------``| Id | Operation     | Name | Rows | Bytes | Cost (%CPU)| Time   |``--------------------------------------------------------------------------``|  0 | SELECT STATEMENT |   |   5 |  135 |  215  (3)| 00:00:03 |``|* 1 | TABLE ACCESS FULL| T  |   5 |  135 |  215  (3)| 00:00:03 |``--------------------------------------------------------------------------``Predicate Information (identified by operation id):``---------------------------------------------------``  ``1 - filter("OBJECT_NAME"='EMPLOYEES')``Statistics``----------------------------------------------------------``     ``0 recursive calls``     ``0 db block gets``    ``942 consistent gets``     ``0 physical reads``     ``0 redo size``    ``538 bytes sent via SQL*Net to client``    ``385 bytes received via SQL*Net from client``     ``2 SQL*Net roundtrips to/from client``     ``0 sorts (memory)``     ``0 sorts (disk)``     ``6 rows processed

不采用hint

SQL> select * from t where object_name='EMPLOYEES';``6 rows selected.``Execution Plan``----------------------------------------------------------``Plan hash value: 2869677071``--------------------------------------------------------------------------``| Id | Operation    | Name | Rows | Bytes | Cost (%CPU)| Time   |``--------------------------------------------------------------------------``|  0 | SELECT STATEMENT |    |   5 |  135 |   5  (0)| 00:00:01 |``|* 1 | INDEX SKIP SCAN | T_IND |   5 |  135 |   5  (0)| 00:00:01 |``--------------------------------------------------------------------------``Predicate Information (identified by operation id):``---------------------------------------------------``  ``1 - access("OBJECT_NAME"='EMPLOYEES')``    ``filter("OBJECT_NAME"='EMPLOYEES')``Statistics``----------------------------------------------------------``     ``1 recursive calls``     ``0 db block gets``     ``17 consistent gets``     ``1 physical reads``     ``0 redo size``    ``538 bytes sent via SQL*Net to client``    ``385 bytes received via SQL*Net from client``     ``2 SQL*Net roundtrips to/from client``     ``0 sorts (memory)``     ``0 sorts (disk)``     ``6 rows processed

当全表扫描扫描了942个块,联合索引只扫描了17个数据块。可以看到联合索引的第一个字段的值重复率很高时,即使谓词中没有联合索引的第一个字段,依然会使用index_ss方式,效率远远高于全表扫描效率。但当 第一个字段的值重复率很低时,使用 index_ss的效率要低于 全表扫描,读者可以自行实验

和表的关联相关的hint

/*+ leading(table_1,table_2) */

在多表关联查询中,指定哪个表作为驱动表,即告诉优化器首先要访问哪个表上的数据。

select /*+ leading(t,t1) / t. from t,t1 where t.id=t1.id; /*+ order */

让Oracle根据from后面表的顺序来选择驱动表,oracle建议使用leading,他更为灵活

select /*+ order / t. from t,t1 where t.id=t1.id;

/*+ use_nl(table_1,table_2) */ 在多表关联查询中,指定使用nest loops方式进行多表关联。

select /*+ use_nl(t,t1) / t. from t,t1 where t.id=t1.id;

/*+ use_hash(table_1,table_2) */ 在多表关联查询中,指定使用hash join方式进行多表关联。

select /*+ use_hash(t,t1) / t. from t,t1 where t.id=t1.id;

在多表关联查询中,指定使用hash join方式进行多表关联,并指定表t为驱动表。

select /*+ use_hash(t,t1) leading(t,t1) / t. from t,t1 where t.id=t1.id;

/*+ use_merge(table_1,table_2) */ 在多表关联查询中,指定使用merge join方式进行多表关联。

select /*+ use_merge(t,t1) / t. from t,t1 where t.id=t1.id;

/*+ no_use_nl(table_1,table_2) */ 在多表关联查询中,指定不使用nest loops方式进行多表关联。

select /*+ no_use_nl(t,t1) / t. from t,t1 where t.id=t1.id;

/*+ no_use_hash(table_1,table_2) */ 在多表关联查询中,指定不使用hash join方式进行多表关联。

select /*+ no_use_hash(t,t1) / t. from t,t1 where t.id=t1.id;

/*+ no_use_merge(table_1,table_2) */ 在多表关联查询中,指定不使用merge join方式进行多表关联。

select /*+ no_use_merge(t,t1) / t. from t,t1 where t.id=t1.id;

其他常用的hint

/*+ parallel(table_name n) */

在sql中指定执行的并行度,这个值将会覆盖自身的并行度

select /*+ parallel(t 4) / count() from t;

/*+ no_parallel(table_name) */

在sql中指定执行的不使用并行

select /*+ no_parallel(t) / count() from t;

/*+ append */以直接加载的方式将数据加载入库

insert into t /*+ append */ select * from t;

/*+ dynamic_sampling(table_name n) */

设置sql执行时动态采用的级别,这个级别为0~10 select /*+ dynamic_sampling(t 4) */ * from t where id > 1234

/*+ cache(table_name) */ 进行全表扫描时将table置于LRU列表的最活跃端,类似于table的cache属性

select /*+ full(employees) cache(employees) */ last_name from employees

循环插入多条测试数据

declare begin for i in 1..100 loop insert into hsraw.cjz54_n_branch(oc_date,source_flag,brhid,brhname) values(20210219,'m',i,'测试'||i); end loop; --commit; end;

declare v_branch_no number; begin select max(t.branch_no) into v_branch_no from hsraw.cuf3_n_pbs_all_branch t; for i in 1..100 loop insert into hsraw.cuf3_n_pbs_all_branch(oc_date,branch_no) values(20201130,v_branch_no+1); v_branch_no:=v_branch_no+1; end loop; -- commit; end;

oracle游标

隐式游标:select A.a into v_a from A;

显示游标:

open v_stockcode_cursor for select t.dep_id, count(1) as cntfrom hsics.iso_sensitive_insider twhere t.review_status = '2'      --待复核group by t.dep_id;
loop fetch v_stockcode_cursor into v_dep_list, v_count1;
exit when v_stockcode_cursor%notfound;

绑定变量

绑定变量是什么?绑定变量有什么优缺点? 绑定变量是指在SQL语句中使用变量,改变变量的值来改变SQL语句的执行结果。 优点:使用绑定变量,可以减少SQL语句的解析,能减少数据库引擎消耗在SQL语句解析上的资源。提高了编程效率和可靠性。减少访问数据库的次数, 就能实际上减少ORACLE的工作量。 缺点:经常需要使用动态SQL的写法,由于参数的不同,可能SQL的执行效率不同;

绑定变量是相对文本变量来讲的,所谓文本变量是指在SQL直接书写查询条件, 这样的SQL在不同条件下需要反复解析,绑定变量是指使用变量来代替直接书写条件,查询bind value在运行时传递,然后绑定执行。 优点是减少硬解析,降低CPU的争用,节省shared_pool 缺点是不能使用histogram,sql优化比较困难

拉链表

--代码实现流程 --建立源数据 create table test_src ( ID varchar2(100), NAME varchar2(100), BAL number(20,2) );

--往源中插入数据 insert into test_src select '1','徐峥',600 from dual union all select '2','黄渤',700 from dual;

--建立目标表 create table test_tag ( ID varchar2(100), NAME varchar2(100), BAL number(20,2), START_DT date, END_DT date );

--建立临时表temp1 --用于存放原系统数据

--事务临时表 create global temporary table temp1 as select * from test_tag;

--建立第二个临时表temp2 --用于存放对比后的增量或是状态有变化的数据 create global temporary table temp2 --事务临时表 as select * from test_tag;

--临时表temp1插入数据 --此处方便测试,使用前天时间 insert into temp1 select a.id, a.name, sum(bal),trunc(sysdate-2,'dd'),to_date('29990101','yyyy/mm/dd') from test_src a group by a.id, a.name

select t.*,rowid from test_src t; select * from test_tag; select * from temp1; select * from temp2;

--临时表temp2插入数据 insert into temp2 SELECT * FROM temp1 t1 WHERE not exists( SELECT 1 FROM test_tag g WHERE g.END_DT=to_date('29990101','yyyy/mm/dd') and t1.id=g.id and t1.bal=g.bal);

--关链 --此处方便测试,使用前天时间

update test_tag a set end_dt=trunc(sysdate-2,'dd') where exists (select 1 from temp2 b where a.id=b.id) and END_DT = to_date('29990101','yyyy/mm/dd');

--开链 insert into test_tag select * from temp2; commit;

--查看目标表

select * from test_tag;

--修改数据再次测试 --修改和插入数据 update test_src set bal=2700 where id=2; insert into test_src values(3,'黄晓明',1000); commit;

select * from test_src;

--插入到临时表temp1 --此时为测试方便使用昨天时间

insert into temp1 select a.*,trunc(sysdate-1,'dd'),to_date('29990101','yyyy/mm/dd') from test_src a

--插入到临时表temp2 insert into temp2 SELECT * FROM temp1 t1 WHERE not exists( SELECT 1 FROM test_tag g WHERE g.END_DT=to_date('29990101','yyyy/mm/dd') and t1.id=g.id and t1.bal=g.bal);

--关链 update test_tag a set end_dt=trunc(sysdate-1,'dd') where exists (select 1 from temp2 b where a.id=b.id) and END_DT = to_date('29990101','yyyy/mm/dd');

--开链 insert into test_tag select * from temp2; commit;

select * from test_tag;

--查看23号大家的余额情况

select * from test_tag where start_dt<=to_date('20210817','yyyy/mm/dd') and end_dt>to_date('20210817','yyyy/mm/dd');

分区表

oracle表分区创建

一、什么是分区表 表分区有以下优点: 1、数据查询:数据被存储到多个文件上,减少了I/O负载,查询速度提高。 2、数据修剪:保存历史数据非常的理想。 3、备份:将大表的数据分成多个文件,方便备份和恢复。 4、并行性:可以同时向表中进行DML操作,并行性性能提高,均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。 5、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用; 6、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可; 7、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。 8、需要注意的是包含LONG、LONGRAW数据类型的表不能分区,如果表格大于2G需要考虑分区。

二、分区表的种类 1、RANGE 范围分区 说明:针对记录字段的值在某个范围。 规则: (1)、每一个分区都必须有一个VALUES LESS THEN子句,它指定了一个不包括在该分区中的上限值。 分区键的任何值等于或者大于这个上限值的记录都会被加入到下一个高一些的分区中。 (2)、所有分区,除了第一个,都会有一个隐式的下限值,这个值就是此分区的前一个分区的上限值。 (3)、在最高的分区中,MAXVALUE被定义。MAXVALUE代表了一个不确定的值。这个值高于其它分区中的任何分区键的值, 也可以理解为高于任何分区中指定的VALUE LESS THEN的值,同时包括空值。若不添加maxvalue的分区插入数值一旦超过设置的最大上限会报错。

例一,按date范围创建分区表

CREATE TABLE PART_TAB_CUSTOMER_BY_RANGE
( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, FIRST_NAME VARCHAR2(30) NOT NULL, LAST_NAME VARCHAR2(30) NOT NULL, PHONE VARCHAR2(15) NOT NULL, EMAIL VARCHAR2(80), SEX VARCHAR2(10),STATUS VARCHAR2(10),INSERT_DATE DATE
)
PARTITION BY RANGE (INSERT_DATE) --按时间分区
( PARTITION DATE_RANGE1 VALUES LESS THAN (TO_DATE(' 2001-01-01', 'YYYY-MM-DD')) TABLESPACE part_Data1, PARTITION DATE_RANGE2 VALUES LESS THAN (TO_DATE(' 2007-01-01', 'YYYY-MM-DD')) TABLESPACE part_Data2,PARTITION DATE_RANGE3 VALUES LESS THAN (maxvalue) TABLESPACE part_Data3
) 

例二、按照number范围分区

PARTITION BY RANGE (CUSTOMER_ID) --按id分区
( PARTITION CUS_PART1 VALUES LESS THAN (100000) TABLESPACE part_Data1, PARTITION CUS_PART2 VALUES LESS THAN (200000) TABLESPACE part_Data2,PARTITION CUS_PART2 VALUES LESS THAN (maxvalue) TABLESPACE part_Data3
)

2、LIST 列表分区 说明:该分区的特点是某列的值只有有限个值,基于这样的特点我们可以采用列表分区。 规则:默认分区为DEFAULT,若不添加DEFAULT的分区插入数值不属于所设置的分区会报错。 例一、姓氏

CREATE TABLE PART_TAB_CUSTOMER_BY_LIST
( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, PHONE VARCHAR2(15) NOT NULL, EMAIL VARCHAR2(80), SEX VARCHAR2(10),CORP_ID VARCHAR2(3),INSERT_DATE DATE,SUM_DATE varchar2(4)
)
PARTITION BY LIST (SEX)
( PARTITION MALE      VALUES ('男')    TABLESPACE part_Data1, PARTITION FEMALE    VALUES ('女')    TABLESPACE part_Data2
) 

例二、varchar2的日期

PARTITION BY LIST (SUM_DATE)
( PARTITION SUM_DATE1    VALUES ('2012')    TABLESPACE part_Data1, PARTITION SUM_DATE2    VALUES ('2013')    TABLESPACE part_Data2,PARTITION SUM_DATE2    VALUES (DEFAULT)    TABLESPACE part_Data2
) 

3、HASH 散列分区 说明:这类分区是在列值上使用散列算法,以确定将行放入哪个分区中。 规则:当列的值没有合适的条件,没有范围的规律,也没有固定的值,建议使用散列分区。 散列分区为通过指定分区编号来均匀分布数据的一种分区类型,因为通过在I/O设备上进行散列分区, 使得这些分区大小一致。建议分区的数量采用2的n次方,这样可以使得各个分区间数据分布更加均匀。

创建hash分区有两种方法:一种方法是指定分区的名字,另一种方法是指定分区数量。

例一、常规方法指定分区名字

CREATE TABLE PART_TAB_CUSTOMER_BY_HASH
( CUSTOMER_ID NUMBER NOT NULL PRIMARY KEY, FIRST_NAME VARCHAR2(30) NOT NULL, LAST_NAME VARCHAR2(30) NOT NULL, PHONE VARCHAR2(15) NOT NULL, EMAIL VARCHAR2(80), SEX VARCHAR2(10),STATUS VARCHAR2(10),INSERT_DATE DATE
)
PARTITION BY HASH (CUSTOMER_ID) --按id散列
( PARTITION hash1 TABLESPACE part_Data1, PARTITION hash2 TABLESPACE part_Data2
) 

例二、指定分区数量 PARTITION BY HASH (empno) PARTITIONS 2 STORE IN (part_Data1,part_Data2); --往往我们不需要知道bash分区的名字,因为数据放在哪个分区是oracle根据bash算法存放的,并不是用户指定, 所以当用户插入一条记录,并不能确定放在哪个分区,这个不同于range和list

3、复合分区 说明:顾名思义,复合分区就由range+list+hash两两组合而来,一般分为range+list,list+range,range+hash,list+bash,这里指列出几种常用组合。 规则:如果组合中存在hash,皆把hash分区作为子分区,原因大家可以通过hash分区的性质知道。 例一、range+list,这种分区是基于范围分区和列表分区,表首先按某列进行范围分区,然后再按某列进行列表分区。

CREATE TABLE PART_TAB_SALE_RANGE_LIST
( PRODUCT_ID VARCHAR2(5), SALES_DATE DATE, SALES_COST NUMBER(10), STATUS VARCHAR2(10),
)
PARTITION BY RANGE(SALES_DATE) SUBPARTITION BY LIST (STATUS)
( PARTITION P1 VALUES LESS THAN (TO_DATE('2003-01-01','YYYY-MM-DD')) TABLESPACE part_Data1 ( SUBPARTITION P1SUB1 VALUES ('ACTIVE') TABLESPACE part_Data1, SUBPARTITION P1SUB2 VALUES ('INACTIVE') TABLESPACE part_Data2,SUBPARTITION P1SUB3 VALUES (DEFAULT) TABLESPACE part_Data3), PARTITION P2 VALUES LESS THAN (TO_DATE('2003-03-01','YYYY-MM-DD')) TABLESPACE part_Data2 ( SUBPARTITION P2SUB1 VALUES ('ACTIVE') TABLESPACE part_Data1, SUBPARTITION P2SUB2 VALUES ('INACTIVE') TABLESPACE part_Data2,SUBPARTITION P2SUB3 VALUES (DEFAULT) TABLESPACE part_Data3 ),PARTITION P3 VALUES LESS THAN (maxvalue) TABLESPACE part_Data3( SUBPARTITION P3SUB1 VALUES ('ACTIVE') TABLESPACE part_Data1,SUBPARTITION P3SUB2 VALUES ('INACTIVE') TABLESPACE part_Data2,SUBPARTITION P3SUB3 VALUES (DEFAULT) TABLESPACE part_Data3)
) 

例二、range+bash,这种分区是基于范围分区和散列分区,表首先按某列进行范围分区,然后再按某列进行散列分区。

partition by range(transaction_date)
subpartition by hash(transaction_id) subpartitions 3 store in (dinya_space01,dinya_space02,dinya_space03)
(partition part_01 values less than(to_date(‘2006-01-01’,’yyyy-mm-dd’)),
partition part_02 values less than(to_date(‘2010-01-01’,’yyyy-mm-dd’)),
partition part_03 values less than(maxvalue)
);

三、分区表的操作 1.DML操作 说明:DML操作和平常的表一样,有异于的地方是增加了可以指定表的特定分区才执行DML操作。

例如,查询分区表

SELECT * FROM PART_TAB_SALE_RANGE_LIST;--不指定分区直接查询
SELECT * FROM PART_TAB_SALE_RANGE_LIST PARTITION(P2);--指定分区查询
SELECT * FROM PART_TAB_SALE_RANGE_LIST SUBPARTITION(P1SUB2);--指定小分区查询

对于分区表,指定分区执行DML效率更高,但,如果指定了分区,而条件中的数据又不在该分区中时,将不会产生任何DML操作。

2.DDL操作 1)添加分区 (1)对range分区表添加分区 ALTER TABLE PART_TAB_SALE_RANGE_LIST ADD PARTITION P3 VALUES LESS THAN(TO_DATE('2009-06-01','YYYY-MM-DD')); 注意:增加一个分区的时候,增加的分区的条件必须大于现有分区的最大值,否则系统将提示ORA-14074 partition bound must collate higher than that of the last partition 错误。 (2)对range分区表list子分区添加分区 ALTER TABLE PART_TAB_SALE_RANGE_LIST MODIFY PARTITION P3 ADD SUBPARTITION P3SUB1 VALUES('COMPLETE');

2)删除分区 (1)对range分区表删除分区 ALTER TABLE PART_TAB_SALE_RANGE_LIST DROP PARTITION P3; (2)对range分区表list子分区删除子分区 ALTER TABLE PART_TAB_SALE_RANGE_LIST DROP SUBPARTITION P4SUB1;

注意:如果删除的分区是表中唯一的分区,那么此分区将不能被删除,要想删除此分区,必须删除表。

3)截断分区 说明:截断某个分区是指清空某个分区中的数据,并不会删除分区,也不会删除其它分区中的数据。当表中即使只有一个分区时,也可以截断该分区。 注意:如果截断的分区表有约束,需要先关闭约束。alter table sales disable/enable constraint restraint_name,截断分区会使全局索引无效,需要重建。 (1)清空分区: ALTER TABLE SALES TRUNCATE PARTITION P2;--这种方式使全局分区索引无效 ALTER TABLE SALES TRUNCATE PARTITION P2 update indexes;--这种方式使全局分区索引有效UPDATE GLOBAL INDEXES

(2)清空子分区: ALTER TABLE PART_TAB_SALE_RANGE_LIST TRUNCATE SUBPARTITION P2SUB2; ALTER TABLE PART_TAB_SALE_RANGE_LIST TRUNCATE SUBPARTITION P2SUB2 update indexes;

4)合并分区 说明:合并分区是将相邻的分区合并成一个分区,结果分区将采用较高分区的界限,值得注意的是,不能将分区合并到界限较低的分区。 ALTER TABLE PART_TAB_SALE_RANGE_LIST MERGE PARTITIONS P1,P2 INTO PARTITION P2; 注意:在本例中将原有的表的part_01分区和part_02分区进行了合并,合并后的分区为part_02, 如果在合并的时候把合并后的分区定为part_01的时候,系统将提示ORA-14275 cannot reuse lower-bound partition as resulting partition 错误。

5)拆分分区 说明:拆分分区将一个分区拆分两个新分区,拆分后原来分区不再存在。注意不能对HASH类型的分区进行拆分。 ALTER TABLE PART_TAB_SALE_RANGE_LIST SBLIT PARTITION P2 AT(TO_DATE('2003-03-01','YYYY-MM-DD')) INTO (PARTITION P21,PARTITION P22);

6)接合分区 说明:接合分区是将散列分区中的数据接合到其它分区中,当散列分区中的数据比较大时,可以增加散列分区,然后进行接合, 值得注意的是,接合分区只能用于散列分区中。 ALTER TABLE PART_TAB_SALE_RANGE_LIST COALESCA PARTITION;

7)重命名表分区 ALTER TABLE SALES RENAME PARTITION P21 TO P2;

8)移动分区 说明:把分区移动到令一个表空间,移动后要重建索引 alter table sales move partiton sp1 tablespace tablespace_name; alter index index_name rebuild;

--查询是否移动成功 SELECT TABLE_OWNER,TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME,SUBPARTITION_COUNT FROM DBA_TAB_PARTITIONS WHERE TABLE_OWNER='SCOTT';

四、表分区相关的数据字典表 --显示表分区信息 显示数据库所有分区表的详细分区信息: select * from DBA_TAB_PARTITIONS --显示子分区信息 显示数据库所有组合分区表的子分区信息: select * from DBA_TAB_SUBPARTITIONS --显示数据库所有分区表的信息: select * from DBA_PART_TABLES --显示数据库可访问的所有分区表的分区列信息:select * from DBA_PART_KEY_COLUMNS

DBA_IND_PARTITIONS DBA_IND_SUBPARTITIONS

--查询索引信息 select object_name,object_type,tablespace_name,sum(value) from v$segment_statistics where statistic_name IN ('physical reads','physical write','logical reads') and object_type='INDEX' group by object_name,object_type,tablespace_name order by 4 desc

五、局部索引与全局索引 表可以按range,hash,list分区,表分区后,其上的索引和普通表上的索引有所不同,oracle对于分区表上的索引分为2类,即局部索引和全局索引。

分区表2

ORACLE分区表、分区索引详解

详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt160

ORACLE分区表、分区索引ORACLE对于分区表方式其实就是将表分段存储,一般普通表格是一个段存储,而分区表会分成多个段,所以查找数据过程都是先定位根据查询条件定位分区范围,即数据在那个分区或那几个内部,然后在分区内部去查找数据,一个分区一般保证四十多万条数据就比较正常了,但是分区表并非乱建立,而其维护性也相对较为复杂一点,而索引的创建也是有点讲究的,这些以下尽量阐述详细即可。

1、类型说明:

range分区方式,也算是最常用的分区方式,其通过某字段或几个字段的组合的值,从小到大,按照指定的范围说明进行分区,我们在INSERT数据的时候就会存储到指定的分区中。

List分区方式,一般是在range基础上做的二级分区较多,是一种列举方式进行分区,一般讲某些地区、状态或指定规则的编码等进行划分。

Hash分区方式,它没有固定的规则,由ORACLE管理,只需要将值INSERT进去,ORACLE会自动去根据一套HASH算法去划分分区,只需要告诉ORACLE要分几个区即可。

分区可以进行两两组合,ORACLE 11G以前两两组合都必须以range作为一级分区的开头,ORACLE目前最多支持2级别分区,但这个级别已经够我们使用了。

我这只以最简单的分区方式创建分区来说明问题,就拿range分区来说明问题吧(基本创建语句如下):

CREATE [url=]TABLE[/url] TABLE_PARTITION(

COL1 NUMBER,

COL2 VARCHAR2(10)

)

partition by range(COL1)(

partition TAB_PARTOTION_01 values less than (450000),

partition TAB_PARTOTION_02 values less than (900000),

partition TAB_PARTOTION_03 values less than (1350000),

partition TAB_PARTOTION_04 values less than (1800000),

partition TAB_PARTOTION_OTHER values less THAN (MAXVALUE)

);

这个分区表创建了四个定长分区,理想情况下,存储450000条数据,扩展分区是超过这个数额的分区,当发现扩展分区有数据的时候,可以进行将扩展分区做SPLIT操作,这个后面说明,这里先说一下一些常用的分区表查询功能,我们先插入一些数据进去。

INSERT INTO TABLE_PARTITION(COL1,COL2)

VALUES(1,'数据测试');

INSERT INTO TABLE_PARTITION(COL1,COL2)

VALUES(23,'数据测试');

INSERT INTO TABLE_PARTITION(COL1,COL2)

VALUES(449000,'数据测试');

INSERT INTO TABLE_PARTITION(COL1,COL2)

VALUES(450000,'数据测试');

INSERT INTO TABLE_PARTITION(COL1,COL2)

VALUES(1350000,'数据测试');

INSERT INTO TABLE_PARTITION(COL1,COL2))

VALUES(900000,'数据测试');

INSERT INTO TABLE_PARTITION(COL1,COL2)

VALUES(1800000-1,'数据测试');

COMMIT;

为了检测哪些分区中有哪些数据分别按照分区去查询数据(应用开发中基本不会用到,因为不会把分区写死)

SQL> SELECT * FROM TABLE_PARTITION partition(TAB_PARTOTION_01);

COL1 COL2


1 数据测试

23 数据测试

449000 数据测试

说明第一个分区有:1、23、44900这些数据,也就是插入时,ORACLE是自己去找分区的,其实分区这种子表[url=]管理[/url]自己也可以通过程序去完成,ORACLE给你提供了一套,就可以自己去完成了。其余的数据就自己查了,都是一个道理。

2、分区应用:

一般一张表超过2G的大小,ORACLE是推荐使用分区表的,分区一般都需要创建索引,说到分区索引,就可以分为:全局索引、分区索引,即:global索引和local索引,前者为默认情况下在分区表上创建索引时的索引方式,并不对索引进行分区(索引也是表结构,索引大了也需要分区,关于索引以后专门写点)而全局索引可修饰为分区索引,但是和local索引有所区别,前者的分区方式完全按照自定义方式去创建,和表结构完全无关,所以对于分区表的全局索引有以下两幅网上常用的图解:

2.1、对于分区表的不分区索引(这个有点绕,不过就是表分区,但其索引不分区):

创建语法(直接创建即可):

CREATE INDEX <index_name> ON <partition_table_name>(<column_name>);

2.2、对于分区表的分区索引:

创建语法为:

CREATE [url=]INDEX[/url] INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1)

GLOBAL PARTITION BY RANGE(COL1)

PARTITION IDX_P1 values less than (1000000),

PARTITION IDX_P2 values less than (2000000),

PARTITION IDX_P3 values less than (MAXVALUE)

)

2.3、LOCAL索引结构:

创建语法为:

CREATE INDEX INX_TAB_PARTITION_COL1 ON TABLE_PARTITION(COL1) LOCAL;

也可按照分区表的的分区结构给与一一定义,索引的分区将得到重命名。

分区上的位图索引只能为LOCAL索引,不能为GLOBAL全局索引。

2.4、对比索引方式:

一般使用LOCAL索引较为方便,而且维护代价较低,并且LOCAL索引是在分区的基础上去创建索引,类似于在一个子表内部去创建索引,这样开销主要是区分分区上,很规范的管理起来,在OLAP系统中应用很广泛;而相对的GLOBAL索引是全局类型的索引,根据实际情况可以调整分区的类别,而并非按照分区结构一一定义,相对维护代价较高一些,在OLTP环境用得相对较多,这里所谓OLTP和OLAP也是相对的,不是特殊的项目,没有绝对的划分概念,在应用过程中依据实际情况而定,来提高整体的运行性能。

3、常用视图:

1、查询当前用户下有哪些是分区表:

SELECT * FROM USER_PART_TABLES;

2、查询当前用户下有哪些分区索引:

SELECT * FROM USER_PART_INDEXES;

3、查询当前用户下分区索引的分区信息:

SELECT * FROM USER_IND_PARTITIONS T

WHERE T.INDEX_NAME=?

4、查询当前用户下分区表的分区信息:

SELECT * FROM USER_TAB_PARTITIONS T

WHERE T.TABLE_NAME=?;

5、查询某分区下的数据量:

SELECT COUNT(*) FROM TABLE_PARTITION PARTITION(TAB_PARTOTION_01);

6、查询索引、表上在那些列上创建了分区:

SELECT * FROM USER_PART_KEY_COLUMNS;

7、查询某用户下二级分区的信息(只有创建了二级分区才有数据):

SELECT * FROM USER_TAB_SUBPARTITIONS;

4、维护操作:

4.1、删除分区

ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_03;

如果是全局索引,因为全局索引的分区结构和表可以不一致,若不一致的情况下,会导致整个全局索引失效,在删除分区的时候,语句修改为:

ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_03 UPDATE GLOBAL INDEXES;

4.2、分区合并(从中间删除掉一个分区,或者两个分区需要合并后减少分区数量)

合并分区和删除中间的RANGE有点像,但是合并分区是不会删除数据的,对于LIST、HASH分区也是和RANGE分区不一样的,其语法为:

ALTER TABLE TABLE_PARTITION MERGE PARTITIONS TAB_PARTOTION_01,TAB_PARTOTION_02 INTO PARTITION MERGED_PARTITION;

4.3、分隔分区(一般分区从扩展分区从分隔)

ALTER TABLE TABLE_PARTITION SPLIT PARTITION TAB_PARTOTION_OTHERE AT(2500000)

INTO (PARTITION TAB_PARTOTION_05,PARTITION TAB_PARTOTION_OTHERE);

4.4、创建新的分区(分区数据若不能提供范围,则插入时会报错,需要增加分区来扩大范围)

一般有扩展分区的是都是用分隔的方式,若上述创建表时没有创建TAB_PARTOTION_OTHER分区时,在插入数据较大时(按照上述建立规则,超过1800000就应该创建新的分区来存储),就可以创建新的分区,如:

为了试验,我们将扩展分区先删除掉再创建新的分区(因为ORACLE要求,分区的数据不允许重叠,即按照分区字段同样的数据不能同时存储在不同的分区中):

ALTER TABLE TABLE_PARTITION DROP PARTITION TAB_PARTOTION_OTHER;

ALTER TABLE TABLE_PARTITION ADD PARTITION TAB_PARTOTION_06 VALUES LESS THAN(2500000);

在分区下创建新的子分区大致如下(RANGE分区,若为LIST或HASH分区,将创建方式修改为对应的方式即可):

ALTER TABLE <table_name> MODIFY PARTITION <partition_name> ADD SUBPARTITION <user_define_subpartition_name> VALUES LESS THAN(....);

4.5、修改分区名称(修改相关的属性信息):

ALTER TABLE TABLE_PARTITION RENAME PARTITION MERGED_PARTITION TO MERGED_PARTITION02;

4.6、交换分区(快速交换数据,其实是交换段名称指针)

首先创建一个交换表,和原表结构相同,如果有数据,必须符合所交换对应分区的条件:

CREATE TABLE TABLE_PARTITION_2

AS SELECT * FROM TABLE_PARTITION WHERE 1=2;

然后将第一个分区的数据交换出去

ALTER TABLE TABLE_PARTITION EXCHANGE PARTITION TAB_PARTOTION_01

WITH TABLE TABLE_PARTITION_2 INCLUDING INDEXES;

此时会发现第一个分区的数据和表TABLE_PARTITION_2做了瞬间交换,比TRUNCATE还要快,因为这个过程没有进行数据转存,只是段名称的修改过程,和实际的数据量没有关系。

如果是子分区也可以与外部的表进行交换,只需要将关键字修改为:SUBPARTITION 即可。

4.7、清空分区数据

ALTER TABLE <table_name> TRUNCATE PARTITION <partition_name>;

ALTER TABLE <table_name> TRUNCATE subpartition <subpartition_name>;

9、磁盘碎片压缩

对分区表的某分区进行磁盘压缩,当对分区内部数据进行了大量的UPDATE、DELETE操作后,一定时间需要进行磁盘压缩,否则在查询时,若通过FULL SCAN扫描数据,将会把空块也会扫描到,对表进行磁盘压缩需要进行行迁移操作,所以首先需要操作:

ALTER TABLE <table_name> ENABLE ROW MOVEMENT ;

对分区表的某分区压缩语法为:

ALTER TABLE <table_name>

modify partition <partition_name> shrink space;

对普通表压缩:

ALTER TABLE <table_name> shrink space;

对于索引也需要进行压缩,索引也是表:

ALTER INDEX <index_name> shrink space;

10、分区表重新分析以及索引重新分析

对表进行压缩后,需要对表和索引进行重新分析,对表进行重新分析,一般有两种方式:

在ORACLE 10G以前,使用:

BEGIN

dbms_stats.gather_table_stats(USER,UPPER('<table_name>'));

END;

ORACLE 10G后,可以使用:

ANALYZE TABLE <table_name> COMPUTE STATISTICS;

索引重新分析,将上述两种方式分别修改一下,如第一种可以使用:gather_index_stats,而第二种修改为:ANALYZE INDEX即可,不过一般比较常用的是重新编译:

对于分区表并进行了索引分区的情况,需要对每个分区的索引进行重新编译,这里以LOCAL索引为例子(其每个索引的分区和表分区结构相同,默认分区名称和表分区名称相同):

ALTER INDEX <index_name> REBUILD PARTITION <partition_name>;

对于全局索引,根据全局索引锁定义的分区名称修改即可,若没有分区,和普通单表索引重新编译方式相同:

ALTER INDEX <index_name> REBUILD;

11、关联对象重新编译,

上述对表、索引进行重新编译,尤其对表进行了压缩后会产生行迁移,这个过程可能会导致一些视图、过程对象的失效,此时要将其重新编译一次。

12、扩展:HASH分区中,如果创建了新的分区,可以将其进行重新HASH分布:

ALTER TABLE <table_name> COALESCA PARTITION%

5、回归总结:何时建分区,分区类别,索引,如何对应[url=]SQL[/url]

1、创建时机

上述已经说明,2G以上的表,ORACLE推荐创建分区。

分区的方式根据实际情况而定,才能提高整体性能。

分区的字段一定要是经常用以提取数据的字段,否则会在提取过程中导致遍历多个分区,这样比没有分区还要慢。

分区字段要选择合适,数据较为均匀分布到各个分区,不要太多也不要太少,而且根据分区字段可以很快定位到分区范围。

一般情况下,尽量然业务操作在同一个分区内部完成。

2、分区类别

分区主要有RANGE、LIST、HASH;

RANGE通过值的范围分区,也是最常用的分区,这种分区注意在一种变长数字字符串中,很多人会导致认为是数字类型,而按照数字区分区,这样会分布十分不均匀的现象发生。

LIST是列举方式进行分区,一般作为二级分区而存在(当然也可以自己分区,ORACLE 11G后在分区上也可以作为主分区而存在),在RANGE基础上,若数据需要继续分区,并且在RANGE基础上数据量较为固定,只是较大,可以按照一定规则进一步分区。 }

HASH只指定分区个数,分区细节由ORACLE完成,增加HASH分区可以重新分布数据。

注意:分区字段不能使用函数转换后在分区,如,将某数字字符串字段,先TO_NUMER(COL_NAME)后分区。

3、索引类别

大致分:GLOBAL索引和LOCAL索引,钱和可以分:GLOBAL不分区索引,和GLOBAL分区索引。

GLOBAL不分区索引一般不太推荐,因为是用一颗大的索引树来映射一个表,这个过程,这样速度不见得比不分区快。

GLOBAL分区索引,查找数据若通过要通过索引,是先定位了索引内部的分区,然后在这个分区索引中找到ROWID,然后回表提取数据。

LOCAL索引是和分区的个数逐个对应的,可以说先定位分区表的分区也可以说先定位索引的分区,因为他们是一一对应的,找到对应分区后,分区内部索引数据集合。

4、对应应用0

分区表、索引、分区索引,要利用其性能优势,最基本就是要提取数据时,要通过它首先将数据的范围缩小到一个即使做全盘扫描也不会太慢的情况。

所以SQL一定要有分区上的这个字段的一个WHERE条件,将数据迅速定位到分区内部,而且尽量定位到一个分区里面(这个和创建分区的规则有关系)。

建立分区本身不提要性能,要用好才可提高性能,在必要的RAC集群中,若存在多分区提取数据,适当采用并行提取可以提高提取的速度。

对于索引部分,这里也只提到分区索引的创建方式以及常见索引的维护方式,对于索引原理理解后会更容易认识到提取数据时的技巧。

oracle数据库连接及数据导入导出

oracle轻量级客户端配置

  1. 官方下载地址 Oracle Instant Client Downloads

  2. 在解压目录下创建目录network→admin,创建tnsnames.ora文件,配置数据库信息

  3. 打开PLSQL首选项,Oracle --> Connection,在Oracle Home填写D:\develop\oci,OCI library填写D:\develop\oci\oci.dll,具体按照实际情况配

  4. 配置环境变量: TNS_ADMIN ==》 D:\develop\oci\network\admin , NLS_LANG ==》 与所连接数据库的NLS Lang值一致,例如SIMPLIFIED CHINESE_CHINA.ZHS16GBK ,AMERICAN_AMERICA.UTF8 等等

PLSQL连接数据库后不显示别名,在环境变量中配置TNS_ADMIN ==》 D:\develop\oci\network\admin

sqlplus连接远程Oracle数据库的方式

如果已经配置过tnsname

方法一.在运行或者命令窗口里面先输入sqlplus/nolog 再输入 connect username/password@tnsname

方法二.在运行或者命令窗口里面直接输入 sqlplus username/password@tnsname

如果没有配置过tnsname

方法一.在运行或者命令窗口里面先输入sqlplus/nolog 再输入connect username/password@服务器IP:ORACLE端口号/数据库服务名

方法二.在运行或者命令窗口里面直接输入 sqlplus username/passwrod@服务器IP:ORACLE端口号/数据库服务名

dba用户远程登录

sqlplus sys/hegui40@10.20.26.232:1521/hg40db as sysdba;

sqlplus/nolog conn sys/hegui40@10.20.26.232:1521/hg40db as sysdba;

1、默认实例登录,sqlplus username/password 如:sqlplus tas_yn/tas_yn 2、选择实例登录,sqlplus username/password@net_service_name 如:sqlplus tas_yn/tas_yn@orcl10g 3、dba用户登录,sqlplus username/password as sysdba 如:sqlplus sys/oracle as sysdba; 4、连接远程数据库实例,sqlplus username/password@host:port/sid 如:sqlplus tas_yn/tas_yn@192.168.0.101:1521/orcl10g

Oracle创建DBLink

1.查询当前用户是否具有创建dblink的权限

select * from user_sys_privs where privilege like upper('%DATABASE LINK%') and username = '大写的当前用户名';

2.用sys用户赋权(可直接用sqlplus / as sysdba创建)

grant create public database link,drop public database link to hscon;

3.返回需要创建dblink的用户执行1的语句查看权限是否创建成功

4.可在plsql的object对象中直接创建database links,也可执行创建语句创建

create public database link 连接名称 connect to 要连接的用户名 identified by "要连接的用户密码" USING '要连接的数据库别名'

5.使用当前用户访问连接的数据库对象

select * from 用户.表名@连接名称;

6.还可以将常用的数据库对象建成同义词方便使用;

create synonym 同义词名 FOR 用户.表名@连接名称;
select * from 同义词名;

Oracle导出导入

1、exp和imp是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用。 2、expdp和impdp是服务端的工具程序,他们只能在oracle服务端使用,不能在客户端使用。 3、imp只适用于exp导出的文件,不适用于expdp导出文件;impdp只适用于expdp导出的文件,而不适用于exp导出文件。 4、对于10g以上的服务器,使用exp通常不能导出0行数据的空表,而此时必须使用expdp导出。

SELECT SUM(s.BYTES)/1024/1024 "sizes(MB)" from dba_segments s where s.owner= 'HSICS';

imp 和 exp 命令导入导出数据库

(转自:Oracle 中用 imp 和 exp 命令导入导出数据库(附问题及解决办法)_itbigboy的博客-CSDN博客,尊重原创,本人备忘)

注: 在splplus环境下执行时,在命令前加 ! 号,这样 SQL> !exp … 和 SQL> !imp …

基本语法和实例: \1. EXP 有三种主要的方式(完全、用户、表) 1.1 完全 EXP SYSTEM/MANAGER BUFFER=64000 FILE=C:\FULL.DMP FULL=Y 如果要执行完全导出,必须具有特殊的权限 1.2 用户模式 EXP SONIC/SONIC BUFFER=64000 FILE=C:\SONIC.DMP OWNER=SONIC 这样用户SONIC的所有对象被输出到文件中。 1.3 表模式 EXP SONIC/SONIC BUFFER=64000 FILE=C:\SONIC.DMP OWNER=SONIC TABLES=(SONIC) 这样用户SONIC的表SONIC就被导出 \2. IMP 具有三种模式(完全、用户、表) 1.1 完全: IMP SYSTEM/MANAGER BUFFER=64000 FILE=C:\FULL.DMP FULL=Y 1.2 用户模式: IMP SONIC/SONIC BUFFER=64000 FILE=C:\SONIC.DMP FROMUSER=SONIC TOUSER=SONIC 这样用户SONIC的所有对象被导入到文件中。必须指定FROMUSER、TOUSER参数,这样才能导入数据。 1.3 表模式: EXP SONIC/SONIC BUFFER=64000 FILE=C:\SONIC.DMP OWNER=SONIC TABLES=(SONIC) 这样用户SONIC的表SONIC就被导入。

expdp和ipmdp导入导出

  1. 在导出库和导入库的服务器端创建物理目录和逻辑目录 create directory data_dir as 'C:\ora' ;

  2. 在导出库和导入库进行导入导出赋权:Grant read,write on directory data_dir to scott;

  3. grant exp_full_database,imp_full_database to scott;

  4. 导出全库:expdp scott/scott dumpfile=expdp.dmp directory=data_dir logfile=expdp.log

  5. 将导出的数据源dmp数据泵文件拷贝至导入的服务器C:\ora目录下

  6. impdp scott/scott@hgdb schemas=hsraw directory=data_dir table_exists_action = replace dumpfile=hsraw.dmp logfile=hsraw.log;

  7. impdp scott/scott@orcl REMAP_SCHEMA = scott:scott table_exists_action = replace directory=data_dir dumpfile=expdp.dmp logfile=expdp.log

A电脑上的操作(expdp数据导出):

select * from nls_database_parameters where parameter='NLS_CHARACTERSET'

sqlplus 用户名/密码@ip地址[:端口]/service_name [as sysdba]

  1. 运行cmd;

  2. 登录数据库,输入命令:sqlplus;

    使用管理员角色登录需要在用户名后加“ as sysdba” 例如:sys as sysdba

  3. 创建目录路径:输入命令:create directory data_dir as 'C:\ora' ;

    1、data_dir为路径名称,可自命名,D:\ora为数据库导出文件存放路径(需要现在本地创建对应的路径); 2、使用命令:select * from dba_directories; 可查询用户创建目录。

  4. 为oracle用户授予访问数据目录的权限,输入命令:Grant read,write on directory data_dir to scott;

    dbuser为数据库用户名(与第5步中相同)。

  5. 导入导出操作授权,输入命令:grant exp_full_database,imp_full_database to scott;

  6. 退出,输入命令:exit;

  7. 导出scott用户数据导出:expdp scott/scott schemas=scott dumpfile=expdp.dmp directory=data_dir logfile=expdp.log

  8. 全库导出:expdp USERID='sys/sys as sysdba' dumpfile=expdp.dmp directory=data_dir logfile=expdp.log

  9. 1)导出用户及其对象 expdp scott/scott@hg40db schemas=scott dumpfile=expdp.dmp directory=data_dir logfile=expdp.log

    2)导出指定表 expdp scott/scott@orcl tables=emp,dept dumpfile=expdp.dmp directory=data_dir logfile=expdp.log;

    3)按查询条件导 expdp scott/scott@orcl directory=data_dir dumpfile=expdp.dmp tables=empquery='where deptno=20' logfile=expdp.log

    4)按表空间导 expdp scott/scott@orcl directory=data_dir dumpfile=tablespace.dmp tablespaces=temp,example logfile=expdp.log

    5)导整个数据库 expdp scott/scott@hg40db directory=data_dir dumpfile=expdp.dmp full=y logfile=expdp.log

  10. 加上full = y时,会导出所有库里面的表,包括Oracle默认的一些sys的表

expdp [为用户名]/[密码]@[服务名]schemas=[为用户名]dumpfile=[导出数据库文件(可自命名)]directory=[目录名]logfile=[日志文件文件名(可自命名)] 注意:命令结束不需要加“;”!

B电脑上的操作(impdp 数据导入):

  1. 运行cmd;

  2. 登录数据库,输入命令:sqlplus

    使用管理员角色登录需要在用户名后加“ as sysdba” 例如:sys as sysdba

  3. 创建目录路径:输入命令:create directory data_dir as 'E:\ora\data' ;

    1、data_dir为路径名称,可自命名,E:\ora\data为数据库导出文件存放路径(路径必须存在); 2、使用命令:select * from dba_directories可查询用户创建目录。

  4. 为oracle用户授予访问数据目录的权限,输入命令:Grant read,write on directory data_dir to dbuser;

    dbuser为数据库用户名(与第5步中相同)。

  5. 导入导出操作授权,输入命令:grant exp_full_database,imp_full_database to dbuser;

  6. 将从A电脑中E:\ora\data目录下的.dmp数据泵导出文件拷贝至B电脑创建的目录(E:\ora\data)中;

  7. 退出,输入命令:exit;

  8. 数据导入,执行命令:impdp scott/scott REMAP_SCHEMA = hsods:hsods table_exists_action = replace directory=data_dir dumpfile=hsods.dmp logfile=hsods.log

    impdp [用户名]/[密码]@[服务名]REMAP_SCHEMA=[源用户名1]:[目标用户名2]table_exists_action=replace /*存在的表动作(覆盖)*/directory=[目录名]dumpfile=[.dmp文件名]logfile=[.log文件名] 注意:命令结束不需要加“;”!

Oracle创建、查看、修改、赋权、删除directory目录

创建directory一般是为了用数据泵导入/导出数据用, 创建directory语法:

CREATE [OR REPLACE] DIRECTORY directory AS 'pathname';

例如:

create or replace directory dumpdir as '/home/oracle/datatmp'
这样把目录/home/oracle/datatmp设置成dumpdir代表的directory

查看directory路径

select * from dba_directories;

修改directory

create or replace directory dumpdir as '/home/dumpfiles';

要更改dumpdir目录的路径为/home/dumpfiles

directory赋权

grant read,write on directory dumpdir to username;

directory删除

drop directory DIRENAME;

Linux导入导出Oracle数据库

2018-03-30 15:23 yanch1 阅读(15132) 评论(0) 编辑 收藏

一 导出

1.在Linnux服务器上如果不是oracle用户,则要切换到oracle用户。

命令如下:

su - oracle

2.exp导出工具

exp导出工具将数据库中数据备份压缩成一个二进制系统文件,可以在不同OS间迁移。

exp导出工具又分为交互式命令行方式非交互式命令行方式 .

(1)交互式命令行方式

exp username(用户名)/password(口令)@servicename(数据库服务名)

例如

$exp ttt/123@sername Enter array fetch buffer size: 4096 > 回车 Export file: expdat.dmp > t.dmp 导出的文件名

(1)E(ntire database), (2)U(sers), or (3)T(ables): (2)U > 3

1:整个数据库 2:所有的用户,schema 3:所有的表

Export table data (yes/no): yes > no

是否导出表中的数据 Compress extents (yes/no): yes > 回车

是否压缩

Export done in US7ASCII character set and UTF8 NCHAR character set server uses AL32UTF8 character set (possible charset conversion) About to export specified tables via Conventional Path ...

Table(T) or Partition(T:P) to be exported: (RETURN to quit) > t 要导出的表名

. . exporting table t Table(T) or Partition(T:P) to be exported: (RETURN to quit) >要导出的表名n Table(T) or Partition(T:P) to be exported: (RETURN to quit) > 回车 Export terminated successfully without warnings.

(2)交互式命令行方式

exp username/password@service_name file=/home/oracle/databasename.dmp

username:用户名

password:密码

service_name:数据库的服务名

file:要导出数据库文件的路径

二 导入

1.在要导入的oracle数据库上创建相应的用户,只有拥有IMP_FULL_DATABASE和DBA权限的用户才能做整个数据库导入。

create user scott identified by scott; grant dba to scott;

2.导入前Linux服务器切换到oracle用户

su - oracle

3.imp导入工具

导入工具imp也分交互式和非交互式

(1)交互式命令行方式

$ imp

Username: username Password: password

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options

Import data only (yes/no): no >

是否只导入数据

Import file: expdat.dmp > /t/t.dmp

导入数据库文件的路径

Enter insert buffer size (minimum is 8192) 30720>

输入插入缓冲区大小(最小为 8192 )

Export file created by EXPORT:V10.02.01 via conventional path import done in ZHS16GBK character set and AL16UTF16 NCHAR character set export client uses US7ASCII character set (possible charset conversion) export server uses UTF8 NCHAR character set (possible ncharset conversion) List contents of import file only (yes/no): no >

只列出导入文件的内容

Ignore create error due to object existence (yes/no): no > yes

由于对象已存在, 忽略创建错误

Import grants (yes/no): yes >

导入权限

Import table data (yes/no): yes >

导入表数据

Import entire export file (yes/no): no > yes

导入整个导出文件

. importing XXXXXXobjects into XXXXXX . . importing table "t" 2775 rows imported Import terminated successfully with warnings.

(2)交互式命令行方式

$ imp usrname/password file = t.dmp full=y

三 注意事项

1.oracle数据库导出时老是遇到一错误.ora-12641:验证服务无法初始化

这个问题的标准代码应该为 tns-12641(ora-12500到ora-12699的错误,应该是tns-12500到tns-12699).

网络问题,从网络方面着手

将sqlnet.ora文件中的SQLNET.AUTHENTICATION_SERVICES = (TNS)

修改为SQLNET.AUTHENTICATION_SERVICES = (none)

linux下 oracle怎么导入dmp文件

先创建数据库用户: create user XXX identified by xxx default tablespace XXXXX; grant connect,resource,dba to XXX ;

数据库: 用户名:XXXX 密码:XXXX 服务器连接地址和SID:10.XX.XX.XXX:1521/orcl

1、给dmp文件加权限 chmod 777 /home/userct/oss-shanxi/DbBackup20180328.dmp

2、切换用户: $ su oracle

3、导入数据库文件 imp 用户名/密码@orcl file=/home/userct/oss-shanxi/DbBackup20180328.dmp ignore=y full=y;

报错:IMP-00002: failed to open /home/userct/oss-shanxi/DbBackup20180328.dmp for read

错误原因: oracle 账户没有对指定目录的读/写权限

解决: 更换到Oracle有读写权限的相关目录 将dmp文件存放到/home/oracle路径下 再切换到oracle用户下 $ cd /root $ su oracle imp file=/home/oracle/DbBackup20180328.dmp ignore=y full=y; 还是报错:

错误原因: 没有给该dmp 文件赋予权限

解决: ctrl + d $ su root 切换用户 $ chmod 777 /home/oracle/DbBackup20180328.dmp

再切换oracle 用户执行 $ cd /root $ su oracle imp 用户名/密码@orcl file=/home/oracle/DbBackup20180328.dmp ignore=y full=y; 打印 successfully表示导入成功

exp hscon/hscon@xhgdevdb

exp hscon/hscon@xhgdevdb file=/home/oracle/databasename.dmp

imp hswfl/hswfl file=/data/hgxtdb/datafile/hswfl.dmp ignore=y full=y

imp scott/scott@hgxtdb file=/data/hgxtdb/datafile/1.dmp ignore=y full=y;

exp zsj_trade_bj/zhulong BUFFER=64000 FILE=/home/oracle/database/jc.dmp owner="(zsj_trade_bj,zsj_trade_zs,zsj_trade_ls,zsj_center)"

imp jcrz_trade_bj/zhulong file=/home/oracle/database/jc.dmp fromuser=zsj_trade_bj touser=jcrz_trade_bj;

--查看数据库默认表空间位置 select t1.name,t2.name from v$tablespace t1,v$datafile t2 where t1.ts# = t2.ts#;

先创建数据库用户: create user scott identified by scott; grant connect,resource,dba to scott ;

数据库: 用户名:scott 密码:scott 服务器连接地址和SID:10.XX.XX.XXX:1521/orcl

chmod 777 /data/hgxtdb/datafile/1.dmp

exp hscon/hscon Enter array fetch buffer size: 4096 > (回车)

Export file: expdat.dmp > /data/xhgdevdb/datafile/b.dmp

(2)U(sers), or (3)T(ables): (2)U > 3 (所有的表)

Export table data (yes/no): yes > yes (是否导出表数据)

Compress extents (yes/no): yes > (是否压缩) Export terminated successfully with warnings.

查看dmp文件 一般有2个很好的解决方案 1)unix/liux下 strings expdp.dmp |grep "CREATE TABLE"|sed -e 's/,/,\n/g' Windows下 用UltraEdit或其他编辑工具打开后查看(不过效果不如strings 看到的爽)

2.使用imp ... show=y log=scripts.sql 的方式,可以看到清晰的ddl脚本!

oracle表空间及用户

通过FLASHBACK TABLE实现已删除数据恢复

chiclewu 2013-11-22 02:10:23 14630 收藏 6 分类专栏: Backup and Recovery 文章标签: flashback table 恢复删除记录 闪回表操作 版权

Backup and Recovery 专栏收录该内容 4 篇文章0 订阅 订阅专栏 1.作用 在人为操作或应用程序错误时,使用FLASHBACK TABLE语句恢复表到一个早期状态。表可以闪回到过去的时间点,依赖于系统中撤销数据的数据量。此外,Oracle数据库不能恢复到通过任何DDL操作改变了表结构的早期状态。

(注意:Oracle强烈建议数据库运行在自动撤销模式下,通过设置UNDO_MANAGEMENT初始参数值为AUTO,默认是自动模式。另外,设置UNDO_RETENTION初始化参数的间隔足够大,包括你预计需要的最早数据。)

你不能回滚FLASHBACK TABLE语句。但是,你可以执行另一个FLASHBACK TABLE语句,指定一个早于当前时间的时间点。

2.权限 要闪回一个表到早期的SCN或时间戳。你必须有表的 FLASHBACK对象权限,或者FLASHBACK ANY TABLE系统权限。另外,你必须还有表的 SELECT, INSERT, DELETE和 ALTER对象权限。

闪回列表中的所有表必须启用行移动,除非你是正在闪回表到BEFORE DROP。这种操作叫做闪回删除操作,他使用的是回收站中的删除数据,而不撤销数据。

要闪回表到一个还原点,你必须有SELECT ANY DICTIONARY或FLASHBACK ANY TABLE系统权限,或者SELECT_CATALOG_ROLE角色。

要闪回表到DROP TABLE操作之前。你只需要删除该表的必须权限。

3.语法

语义:

在执行闪回表操作期间,数据库获取闪回列表中所有指定的报表独立DML锁。当正在恢复到之前状态时,这些锁阻止对表的任何操作.

闪回表操作在单个事物中执行,不管闪回表中指定表的数量。要么所有的表都恢复到早期状态,要么都没恢复。如果任何表的闪回表操作失败,那么整个语句都失败。

闪回操作完成时,表中的数据与表之前的时间点一直。但是,FLASHBACK TABLE到SCN或时间戳不保存rowid,FLASHBACK TABLE TO BEFORE DROP不能恢复引用约束。

数据库不能恢复与表关联的早期结构的统计信息。表当前的索引是恢复,并反映还原点表的状态。如果该索引在还原点不存在,数据更新索引里来反映还原点表的状态。然而,如果索引是在当前时间和还原点之间被删除,是不能恢复。

schema

指定模式包含的表。如果缺省,数据库假定该表是在你自己的模式。

table

指定一个或多个表名称。

闪回表收受以下限制:

对于这些对象类型闪回表操作是无效的:表是集群的一部分,物化视图,高级队列表,静态数据字典表,系统表,远程表,对象表,嵌套表,独立分区表和子分区表。 以下DDL操作改变了表的结构,所以不能接着使用 TO SCN或 TO TIMESTAMP闪回到操作之前的时间点:升级,移动,截取表(truncate);增加表约束,增加表到集群;删除或修改列;更改列的加密密钥;增加,删除,合并,分离,联合,截取分区或子分区(除了增加范围分区) TO SCN Clause

指定你要返回表的时间点对应的系统改变号(SCN)。expr必须计算一个数字,代表有效的SCN。

TO TIMESTAMP Clause

指定你要返回表的时间点对应的时间戳。 expr 必须计算一个过去有效的时间戳。表将被闪回到指定时间戳大约3秒内的时间点。

TO RESTORE POINT Clause

指定你要闪回表的还原点,该还原点在之前必须配创建。

ENABLE | DISABLE TRIGGERS

默认情况下,数据库禁用在闪回表操作期间的表上定义的所有启用触发器,在闪回表操作完成之后再启用他们。如果你想覆盖默认的行为,并在执行闪回过程中启用触发器,指定ENABLE TRIGGERS。

TO BEFORE DROP Clause

使用这个子句检索回收站中已删除的表,及其可能依赖的对象。该表必须是驻留在本地管理表空间,而不是其他系统表空间。

你可以指定原始用户指定的表的名称,或对象删除时数据库分配的系统生成名称。

回收站中系统生成的对象名称是唯一的。因此,如果指定系统生成名称,那么数据库检索指定的对象。 要查看回收站中的内容,查询USER_RECYCLEBIN数据字典,也可以使用RECYCLEBIN同义词替代。下面两个语句返回相同行:

select * from recyclebin;

select * from user_recyclebin;

如果指定了用户指定的名称,且如果回收站中包含多个该名称的对象,然后数据库检索回收站中最近移动的对象。如果想要检索更早版本的表,你可以这样做: 指定你想要检索的表的系统生成名称。 执行FLASHBACK TABLE ... TO BEFORE DROP语句,直到你要检索表。 RENAME TO Clause

为从回收站正在检索的表,指定一个新的名称。

4.Examples FLASHBACK TABLE语句的用法主要分成两大类:从撤销数据中闪回和从回收站中闪回。其中从撤销数据中闪回必须要启用表的行移动,用户要有SELECT ANY FLASHBACK系统权限。为了查询闪回事务,用户要有SELECT ANY TRANSACTION系统对象权限。

使用DBA用户给scott用户

GRANT FLASHBACK ANY TABLE TO SCOTT;

GRANT SELECT ANY TRANSACTION TO SCOTT;

4.1.从撤销数据中闪回表到之前某个时间点 使用下面的命令,启用闪回列表中表的行移动:

ALTER TABLE table_name ROW MOVEMENT

创建emp_test测试表

create table emp_test( emp_id number, emp_code varchar2(5), emp_name varchar2(10) );

--插入数据

insert into emp_test values (1,'01','chiclewu'); insert into emp_test values (1,'02','china');

使用下面命令,启用表的行移动:

ALTER TABLE emp_test ENABLE ROW MOVEMENT

需要DBA先授予 select any transaction系统权限给scott用户,查询闪回事务。

SQL> select ftq.start_scn, ftq.start_timestamp 2 from flashback_transaction_query ftq 3 where ftq.table_name = 'EMP_TEST';

START_SCN START_TIMESTAMP


2701570 2013/11/21 22:53:56 2701570 2013/11/21 22:53:56

发现闪回事务查询视图中,有两条撤销数据。现在更新员工代码为02的员工ID为2,姓名修改为“hello”:

SQL> update emp_test et 2 set et.emp_id = 2, et.emp_name = 'hello' 3 where et.emp_code = '02';

1 row updated

SQL> commit;

Commit complete

查询员工表:

SQL> select * from emp_test;

EMP_ID EMP_CODE EMP_NAME

     1 01       chiclewu2 02       hello

员工02的ID和姓名已经修改成功了,并且已经提交了数据。这时候发现修改错了,想要恢复到之前的时间点的数据。可是我没有设置还原点呀!怎么恢复呢?不用担心,使用刚才学过的闪回表SCN或时间戳就能够实现:

先查询闪回事务表中的撤销记录:

SQL> select ftq.start_scn, 2 ftq.start_timestamp 3 from flashback_transaction_query ftq 4 where ftq.table_name = 'EMP_TEST';

START_SCN START_TIMESTAMP


2702778 2013/11/21 23:14:59 2701570 2013/11/21 22:53:56 2701570 2013/11/21 22:53:56

使用闪回表SCN恢复到插入数据之前的时间点:

flashback table emp_test to scn 2701570;

查询员工表:

SQL> select * from emp_test;

EMP_ID EMP_CODE EMP_NAME

没有数据,说明恢复成功!

忽然又觉的不对,又想要恢复到插入数据之后,修改之前的时间点。

使用闪回表时间戳进行恢复: flashback table emp_test to timestamp to_timestamp('2013/11/21 23:14:59','yyyy-mm-dd hh24:mi:ss');

查询员工表:

SQL> select * from emp_test;

EMP_ID EMP_CODE EMP_NAME

     1 01       chiclewu1 02       china

和插入后数据一样,说明恢复成功!

4.2.从撤销数据中闪回表到之前保存点 先设置还原点,用于的数据恢复。

create restore point respt;

删除02员工信息,并提交到事务。

SQL> delete from emp_test t where t.emp_code='02';

1 row deleted

SQL> commit;

Commit complete

查询员工表:

SQL> select * from emp_test;

EMP_ID EMP_CODE EMP_NAME

     1 01       chiclewu

现在使用之前设置的还原点,恢复到还原点时的数据。

flashback table emp_test to restore point respt;

查询员工表

SQL> select * from emp_test;

EMP_ID EMP_CODE EMP_NAME

     1 01       chiclewu1 02       china

有02员工记录,说明保存点闪回恢复成功。

4.3.从回收中恢复删除之前的表 在回收站中只有DROP的对象的数据,没有新增、更新的撤销数据。因此,在回收中只能执行 FALSHBACK TABLE ... TO BEFORE DROP语句。

清空回收站:

pruge recyclebin;

查询回收站

SQL> select object_name, original_name from recyclebin; OBJECT_NAME ORIGINAL_NAME


没有任何记录

首先DROP员工表。

drop table emp_test;

查询员工表

SQL> select * from emp_test;

select * from emp_test

ORA-00942: 表或视图不存在

说明表已经删除了。

在查询回收站

SQL> select object_name, original_name from recyclebin;

OBJECT_NAME ORIGINAL_NAME


BIN$67M/gFgFfovgQAB/AQADTw==$0 EMP_TEST

执行闪回删除恢复:

flashback table "BIN$67M/gFgFfovgQAB/AQADTw==$0" to before drop; --系统生成名称

flashback table EMP_TEST to before drop; --原始表名称

查看员工表:

SQL> select * from emp_test;

EMP_ID EMP_CODE EMP_NAME

     1 01       chiclewu1 02       china

表已经恢复了,数据也恢复了!

5.总结 FLASHBACK TABLE语句能恢复多长时间之前的数据呢?即撤销数据能保留多长时间。

Oracle数据库基于撤销表空间是如何配置的,自动调整撤销保留期限。

撤销表空间是自动扩展的,数据库动态调整撤销保留期限,略长于系统中运行时间最常的主动查询。 撤销表空间是固定大小,UNDO_RETENTION参数值会被忽略。数据库动态调整一个最佳的保留期限。 UNDO_MANAGEMENT初始化参数,默认值为AUTO,即自动撤销管理。UNDO_RETENTION初始化参数,默认值为900(相当于15分钟)。

通过动态数据自定v$undostat,查看最近4天数据库动态动态调整撤销保留期限的值:

select begin_time, end_time, tuned_undoretention from v$undostat order by desc end_time;

描述tablespace和datafile之间的关系

一个表空间可包含一个或多个数据文件。表空间利用增加或扩展数据文件扩大表空间,表空间的大小为组成该表空间的数据文件大小的和。一个datafile只能属于一个表空间; 一个tablespace可以有一个或多个datafile,每个datafile只能在一个tablespace内, table中的数据,通过hash算法分布在tablespace中的各个datafile中,tablespace是逻辑上的概念,datafile则在物理上储存了数据库的种种对象。

查看当前用户的表:

select table_name from user_tables;

3.查看所有用户的表名:

select table_name from all_tables;

4.查看所有表名(其中包括系统表)

select table_name from dba_tables;

5.查看所有的表: select * from tab/dba_tables/dba_objects/cat;

Oracle查询表,过程,用户被锁死或数据库用户密码过期

Oracle数据库用户密码过期

select profile,username from dba_users;--查看当前所有用户,查看用户的默认时间 select * from dba_profiles where profile='DEFAULT' and resource_name='PASSWORD_LIFE_TIME'; alter user hsics identified by hsics; --修改用户密码 ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;--修改用户密码为永久有效

存储过程锁死查询

select * from v$db_object_cache where owner='HSICS' and type in('PROCEDURE','FUNCTION') and locks > 0 and pins > 0;

select * FROM dba_ddl_locks where name =upper('p_iso_exec_restricted_b8');

select t.sid,t.serial# from v$session t where t.sid=&session_id

alter system kill session '183,40650#'

杀死plsqldevlop的进程 tskill plsqldev

查看进程 tasklist

查明所有的用户哪些被锁了

select username,account_status,lock_date from dba_users;

解锁方法 ALTER USER USER_NAME ACCOUNT UNLOCK;

查询被锁住的表及锁表用户

select s.sid, s.serial#, lo.oracle_username, lo.os_user_name, --操作人员计算机用户名 ao.object_name as sys_ics_arg, --被锁表名 s.username, s.schemaname, s.osuser, s.process, s.machine, s.terminal, --操作人员计算机名 lo.locked_mode from v$locked_object lo, all_objects ao, v$session s where ao.object_id = lo.object_id and lo.session_id = s.sid order by s.sid asc;

--3.查出锁定表的sid, serial#,os_user_name, machine_name, terminal,锁的type,mode SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine, s.terminal, s.logon_time, l.type FROM v$session s, v$lock l WHERE s.sid = l.sid AND s.username IS NOT NULL ORDER BY sid;

这个语句将查找到数据库中所有的DML语句产生的锁,还可以发现, 任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。

--杀掉进程 sid,serial# alter system kill session '210,11562';

Oracle删除用户和表空间

删除空表空间,包含物理文件。

drop tablespace b including contents and datafiles cascade constraint;

删除USER。

DROP USER XX CASCADE

删除表空间。

DROP TABLESPACE tablespace_name INCLUDING CONTENTS AND DATAFILES;

删除空的表空间,不包含物理文件。

DROP TABLESPACE tablespace_name;

删除非空表空间,不包含物理文件。

DROP TABLESPACE tablespace_name INCLUDING DATAFILES;

删除非空表空间,包含物理文件。

DROP TABLESPACE tablespace_name INCLUDING CONTENTS AND DATAFILES;

--删除某用户下的所有表 SELECT 'drop table '|| table_name || ';' FROM USER_TABLES ORDER BY TABLE_NAME; --删除某用户下的所有视图 select 'drop view '||view_name||';' from user_views

Oracle表空间不足

  --查询用户所使用的临时表空间:

  select username,default_tablespace,temporary_tablespace from dba_users;

  --查询临时表空间大小以及使用率:

  select tablespace_name, bytes, user_bytes, user_bytes/bytes,file_name from dba_temp_files;

  --查询临时文件是否在线:

  select name,status from v$tempfile;

  --修改临时文件在线(离线)状态:

  alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEMP02.DBF' online(offline);

  --增加临时文件大小(增加原文件):

  alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEMP01.DBF' resize 100m;

  --通过增加新的临时文件,来扩大临时表空间:

  alter tablespace temp add tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEMP02.DBF' size 4000m;

  --删除临时文件:

  alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEMP02.DBF' drop;

  --将临时文件设置为自动扩展:

  alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEMP01.DBF' autoextend on next 5m maxsize unlimited;

  --关闭(启动)临时文件的自动增长:

alter database tempfile 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEMP01.DBF' autoextend off(on);

oracle函数

正则表达式

REGEXP_REPLACE 函数_gxftry1st的专栏-CSDN博客_regexp_replace

表 1:定位元字符

元字符 说明
^ 使表达式定位至一行的开头
$ 使表达式定位至一行的末尾

表 2:量词或重复操作符

量词 说明
* 匹配 0 次或更多次
? 匹配 0 次或 1 次
+ 匹配 1 次或更多次
{m} 正好匹配 m 次
{m,} 至少匹配 m 次
{m, n} 至少匹配 m 次但不超过 n 次

表 3:预定义的 POSIX 字符类

字符类 说明
[:alpha:] 字母字符
[:lower:] 小写字母字符
[:upper:] 大写字母字符
[:digit:] 数字
[:alnum:] 字母数字字符
[:space:] 空白字符(禁止打印),如回车符、换行符、竖直制表符和换页符
[:punct:] 标点字符
[:cntrl:] 控制字符(禁止打印)
[:print:] 可打印字符

表 4:表达式的替换匹配和分组

元字符 说明
| 替换 分隔替换选项,通常与分组操作符 () 一起使用
( ) 分组 将子表达式分组为一个替换单元、量词单元或后向引用单元(参见"后向引用"部分)
[char] 字符列表 表示一个字符列表;一个字符列表中的大多数元字符(除字符类、^ 和 - 元字符之外)被理解为文字

regexp_replace

替换字符串中的数字或字母,替换为空或指定字符串:select regexp_replace('mak是123号234','[0-9]','') from dual;

select regexp_replace('dajava,dsadsdjava,aa','java','javac',1,0,'i') from dual;

将字符串中的所有中文替换为空:select regexp_replace('张三(883746),李四(2343423)','[:lower:,[:digit:]]','') from dual;

将字符串中的所有除数字之外替换为空:select regexp_replace('张三(883746),李四(2343423)','0-^127','') from dual;

SELECT REGEXP_REPLACE( 'Ellen Hildi Smith', '(.) (.) (.*)', '\3, \1 \2') FROM dual REGEXP_REPLACE('EL ------------------ Smith, Ellen Hildi

把所有的数字替换为空

select regexp_replace('123asxsa456dsQWQE','[0-9]','') from dual;

把所有不是数字的内容替换为空

select regexp_replace('123asxsa456dsQWQE','0-9','') from dual;

  1. 替换字符串

2.使用正则替换第一个字符是数字为a

select regexp_replace('123456788','^[0-9]','a') from dual

3.替换最后一个字符是字母的为9

select regexp_replace('12345678p','[a-zA-Z]$','9') from dual

4.把电话号码+86 13856427896,变换成(+86)138-5642-7896

select regexp_replace('+86 13856427896','(+[0-9]{2})( )([0-9]{3})([0-9]{4})([0-9]{4})','(\1)\3-\4-\5') as new_str from dual;

显示的结果给出了识别重复出现的单词 is 的子字符串。

SELECT REGEXP_SUBSTR( 'The final test is is the implementation', ([[:alnum:]]+)([[:space:]]+)\1') AS substr FROM dual SUBSTR ------ is is

Oracle insert all 详解

1 概述

  1. 作用:'正确、高效' 的将 '同一批数据' 插入至 '不同的表' 中

  2. 好处 (1) '正确':避免数据差异 (2) '高效':优于写多个 insert into(因为无论插入多少张表,'主表' 只会被读取一次)

  3. 场景,若需求:将表 t 中的数据 '同时插入' 至表 t1、t2 若不知晓 insert all 语句,咱可能会使用 insert into 两次 insert into t1 select * from t; insert into t2 select * from t;

    问题:在两次 insert 过程中,有可能 t 表的数据发生了改变, 从而导致 t1、t2 '得到的数据不一致'。

    解决办法:insert all

    2 insert 的两种形式

    1. insert first: 仅对 '第一个' 匹配成功项进行插入

    2. insert all : 对 '每个' 匹配成功项都进行插入

insert first第一个条件满足时,第二个条件就不再插入

insert first when sno >= 2 then -- 不能用别名哦,如:t.sno into stu_info_1(sno, sname, sex) when sno >= 3 then into stu_info_2(sno, sname, sex) select t.sno, t.sname, t.sex from stu_info t;

insert all是满足条件的都会被插入

insert all when sno >= 2 then -- 不能写别名哦,如:t.sno into stu_info_1(sno, sname, sex) when sno >= 3 then into stu_info_2(sno, sname, sex) select t.sno, t.sname, t.sex from stu_info t;

交集,并集

交集:select a from a intersect select a from aa;

并集:select a from a union all select a from aa;

差集:a表里aa表没有的数据:select a from a minus select a from aa;

aa表里a表没有的数据:select a from aa minus select a from a;

oracle随机数 需要用 dbms_random

1、小bai数( 0 ~ 1) select dbms_random.value from dual; 2、指定范围内的小数 ( 0 ~ 100 ) select dbms_random.value(0,100) from dual; 3、指定范围内的整数 ( 0 ~ 100 ) select trunc(dbms_random.value(0,100)) from dual; 4、长度为20的随机数字串 select substr(cast(dbms_random.value as varchar2(38)),3,20) from dual; 5、正态分布的随机数 select dbms_random.normal from dual; 6、随机字符串 select dbms_random.string(opt, length) from dual; opt可取值如下:

  'u','U'    :    大写字母
​'l','L'    :    小写字母
​'a','A'    :    大、小写字母
​'x','X'    :    数字、大写字母
​'p','P'    :    可打印字符

7、随机日期(指定日期的基数+随机的范围,如20210222之后一年的任意一天) select to_date(2459268+TRUNC(DBMS_RANDOM.VALUE(0,365)),'J') from dual

通过下面的语句获得指定日期的基数 select to_char(sysdate,'J') from dual;

select to_char(to_date(20210222,'yyyymmdd'),'J') from dual;

oracle中的greatest 函数和 least函数(取多个数中的最大值和最小值)

greatest(1,2,3,4) :获取一行数据中最大的数值或字符串,以第一个数为准判断是数字或字符串

least (1,2,3,4):获取一行数据中最小的数值或字符串,以第一个数为准判断是数字或字符串

数值会自动转换为字符串,但字符串无法转换为数值,会报无效数字

空值null最大,空格‘ ’最小,多个空格比较时,空格越多越小

rank() over,dense_rank() over,row_number() over的区别

1.rank() over:查出指定条件后的进行排名。特点是,加入是对学生排名,使用这个函数,成绩相同的两名是并列,下一位同学空出所占的名次。

select name,subject,score,rank() over(partition by subject order by score desc) rankfrom student_score;

2.dense_rank() over:与ran() over的區别是,两名学生的成绩并列以后,下一位同学并不空出所占的名次。

select name,subject,score,dense_rank() over(partition by subject order by score desc) rankfrom student_score;

3.row_number() over这个函数不需要考虑是否并列,哪怕根据条件查询出来的数值相同也会进行连续排名

select name,subject,score,row_number() over(partition by subject order by score desc) rankfrom student_score;

4.使用rank() over的时候,空值是最大的,如果排序字段为null,可能造成null字段排在最前面,影响排序结果。可以这样:rank() over(partition by course order by score desc nulls last)来规避这个问题。

select name,subject,score,rank() over(partition by subject order by score desc nulls last) rankfrom student_score;

translate 函数

1.translate 与replace类似是替换函数,但translate是一次替换多个单个的字符。

2.基本用法,字符对应替换。

例子:

select translate('1234567','123' ,'abc') from dual ;--1替换为a,2替换为b,3替换为c

结果:abc4567 。

3.如果 没有对应字符则替换为null;

select translate('1234567','123' ,'ab') from dual;--3替换为null;

结果:ab4567.

4.如果对应字符过多,不影响

select translate('1234567','123' ,'abccd') from dual;

结果:abc4567

5.如果替换字符整个为空字符 ,则直接返回null

select translate('1234567','123' ,'') from dual;

结果:null;

6.如果想筛掉对应字符,应传入一个不相关字符,同时替换字符也加一个相同字符;

select translate('1234567','&123' ,'&') from dual;

结果:4567;

7,如果相同字符对应多个字符,按第一个;

select translate('12334567','1233' ,‘abcd') from dual;

结果:abcc4567;

8,如果想保留某些特定字符筛选掉其他的,比如筛掉汉字保留数字

先把数字筛选掉,

select translate('你师看了3三楼2的6开8发','#0123456789' ,'#') from dual

再用筛选出的汉字去筛选原来的语句留下数字,

select translate('你师看了3三楼2的6开8发','#'||translate('你师看了3三楼2的6开8发','#0123456789' ,'#'),'#') from dual;

结果:3268;

9,还有其他灵活用法,比如我可以判断两个字符串如果:字符串都是数字字符,然后数字字符的顺序不同,且每个字符只出现一次,

我可以判断他们包含的数字是不是完全一致;

比如比较123 和132;

select 1 from dual where translate('0123456789','123' ,'aaaaaaaaaa') =translate('0123456789','132' ,'aaaaaaaaaa')

结果:1 ,也就是where中的等式成立;

今天做项目时,碰到两个表的记录要用union进行合并,但是合并过程中被提示字段类型不匹配,仔细一查发现两个表的字段,一个是varchar2,一个是nvarchar2

以为oracle中也是像mssql中一样,用convert可以转,结果发现不行,经过网上查找资料,发现转换时要用:translate,记下来备忘

例:translate(b.costitemsname using char_cs) as Item_CourseName,

b.costitemsname为要转换的字段名

using char_cs表示用什么类型

多行数据用逗号拼接listagg函数和wm_concat函数

select t.index_id,t.content_name from hsics.iso_manulindexinfo t;

select t.index_id,listagg(t.content_name,',') within group (order by 1) as content_name from hsics.iso_manulindexinfo t group by t.index_id;

select t.index_id,wm_concat(t.content_name) as content_name from hsics.iso_manulindexinfo t group by t.index_id;

sys_connect_by_path start with ... connect by ... prior详解

(Oracle函数sys_connect_by_path 详解 - supermandy - 博客园)

start with后面跟的是要查询的节点字段的值

connect by是关键字,固定写法

prior后面跟的是父节点字段和与父节点字段关联的子节点字段,先跟在prior后面的是父节点

start with ename='King' connect by prior empno= mgr; 表示查找员工‘KING’下面的子节点,即KING的所有下属

start with ename='King' connect by prior mgr= empno;表示查找员工‘KING’上面的子节点,即KING的所有上级

sys_connect_by_path('>') 类似于拼接符号,将每一行的父节点与父节点所对应的子节点的值用()里面的符号连接起来,('>')表示参数符号,可以是任意的字母,数字,符号,但不能被父节点或子节点的值所包含,比如父节点的值是‘1234’,那参数符号就不能是1,2,3,4中的任意一个数字,子节点是‘abc’,那参数符号就不能是a,b,b中的任意一个字母。

语法: Oracle函数:sys_connect_by_path 主要用于树查询(层次查询) 以及 多列转行。其语法一般为: select ... sys_connect_by_path(column_name,'connect_symbol') from table start with ... connect by ... prior 理解: 对于数据库来说,根节点并不一定是在数据库中设计的顶级节点,而是start with开始的地方。sys_connect_by_path函数就是从start with开始的地方开始遍历,并记下其遍历到的节点,start with开始的地方被视为根节点,将遍历到的路径根据函数中的分隔符,组成一个新的字符串。sys_connect_by_path函数用connect by来寻找下一条记录,直到迭代找不到相应记录为止。概念与递归类似,connect by指定递归(连接)条件,如果条件不满足则递归结束。

\1. 查找一个员工的所有下属员工。

start with ename='King' connect by prior empno= mgr; 我是这样理解的:首先数据库中的字段:empno--empname--mgr;这里从'King'开始,把'King'的编号做为管理编号,然后在'King'编号为管理员的员工就是他的下属(循环方式)。

\2. 查找一个员工的所有上司经理。

start with ename='King' connect by prior mgr= empno; 我是这样理解的:首先数据库中的字段:empno--empname--mgr;这里从'King'开始,把'King'的编号做为员工编号,然后在'King'编号的gmr就是他的上司(迭代方式)。

下面是实验:

--CREAT TABLE emp create table emp ( empno varchar2(5), ename varchar2(8), mgr varchar2(8)); --INSERT DATA insert into emp (EMPNO, ENAME, MGR) values ('1', 'jim', '7');

insert into emp (EMPNO, ENAME, MGR) values ('2', 'tom', '7');

insert into emp (EMPNO, ENAME, MGR) values ('3', 'tim', '7');

insert into emp (EMPNO, ENAME, MGR) values ('4', 'lily', '7');

insert into emp (EMPNO, ENAME, MGR) values ('5', 'mary', '7');

insert into emp (EMPNO, ENAME, MGR) values ('6', 'tid', '7');

insert into emp (EMPNO, ENAME, MGR) values ('7', 'King', '10');

insert into emp (EMPNO, ENAME, MGR) values ('8', 'kenvin', '10');

insert into emp (EMPNO, ENAME, MGR) values ('9', 'shema', '8');

insert into emp (EMPNO, ENAME, MGR) values ('10', 'john', '0');

insert into emp (EMPNO, ENAME, MGR) values ('0', 'root', '');

SELECT * FROM emp;

select sys_connect_by_path(ename,'>') tree from emp start with ename='King' connect by prior empno = mgr;

select sys_connect_by_path(ename,'/') tree from emp start with ename='King' connect by prior empno = mgr; --可以理解为查询king的员工 ‘>’与‘/’只是一个输出格式

select sys_connect_by_path(ename,'/') tree from emp start with ename='King' connect by empno= prior mgr; --可以理解为查询king的领导 效果与connect by prior mgr= empno相同

select sys_connect_by_path(ename,'/') tree,level from emp start with ename='King' connect by prior mgr= empno;--可以理解为查询king的领导

总结(自己理解):connect by prior column1 = column2 或者 connect by column2 = prior column1 写法都可以,

主要看prior写在谁的前面,prior写在谁的前面谁就作为父级值(参照值),也就是说[connect by prior column1 = column2]的意思就是是 按start with 条件查询出的记录行,以column1为参考值,查询column2为column1值的记录。

转自:ORACLE函数sys_connect_by_path - 小刺猬学oracle - 博客园

Oracle时间截取

1、获取10分钟前的日期 select sysdate,sysdate-interval '10' minute from dual;

2、获取一周前的日期 select sysdate, sysdate - interval '7' day from dual;

3、获取一个月前的日期 select sysdate,sysdate-interval '1' month from dual;

4、获取一年前的日期 select sysdate,sysdate-interval '1' year from dual;

select add_months(sysdate,-12) from dual ;

5、获取当月的总天数 select to_number(to_char(last_day(sysdate),'dd')) from dual;

6、获取某一个月的总天数 select to_number(to_char(last_day(to_date('2018-09','yyyy-mm')),'dd')) from dual;

7、查询某一个月的全部日期 SELECT TO_CHAR(TRUNC(to_date('2018-09','yyyy-MM'), 'MM') + ROWNUM - 1,'yyyy-MM-dd') someday FROM DUAL CONNECT BY ROWNUM <= TO_NUMBER(TO_CHAR(LAST_DAY(to_date('2018-09','yyyy-MM')), 'dd'))

Oracle获取一周前,一个月前,一年前的日期,一个月的总天数、一个月的全部日期_幸福棒棒糖__fxx的博客-CSDN博客_oracle获取半年前的日期

​
Oracle TRUNC函数可以截取数字和日期类型:截取日期:select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; --显示当前时间
​
select trunc(sysdate,'year') from dual; --截取到年(本年的第一天)
​
select trunc(sysdate,'q') from dual; --截取到季度(本季度的第一天)
​
select trunc(sysdate,'month') from dual; --截取到月(本月的第一天)
​
select trunc(sysdate,'') from dual; --为空
​
select trunc(sysdate) from dual; --截取到日(今天)
​
select to_char(trunc(sysdate),'yyyy-mm-dd hh24:mi:ss') from dual; --默认截取到日(当日的零点零分零秒)
​
select trunc(sysdate,'day') from dual; --截取到周(本周第一天,即上周日)
​
select trunc(sysdate,'iw') from dual; --本周第2天,即本周一
​
select to_char(trunc(sysdate,'dd'),'yyyy-mm-dd hh24:mi:ss') from dual; --截取到日(当日的零点零分零秒)
​
select trunc(sysdate,'hh24') from dual; --截取到小时(当前小时,零分零秒)
​
select trunc(sysdate,'mi') from dual; --截取到分(当前分,零秒)
​
select trunc(sysdate,'ss') from dual ;--报错,没有精确到秒的格式截取数值:trunc(number,decimals) number:指需要截取的数字
select trunc(122.555) from dual t; --默认取整
select trunc(122.555,2) from dual t;
select trunc(122.555,-2) from dual t;--负数表示从小数点左边开始截取2位

今日早晨在客户反馈不能登陆系统了,查看oracle日志。发现如下错误ORA-00257: archiver error. Connect internal only, until freed。 该错误是由于归档日志满了,造成的。 查看了下V$FLASH_RECOVERY_AREA_USAGE,看看归档目录使用的情况。果然是归档满了。

SQL> SELECT * FROM V$FLASH_RECOVERY_AREA_USAGE;

FILE_TYPE PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE NUMBER_OF_FILES


CONTROLFILE 0 0 0

ONLINELOG 0 0 0

ARCHIVELOG 99.9 0 255

BACKUPPIECE 0 0 0

IMAGECOPY 0 0 0

FLASHBACKLOG 0 0 0

注:可以看出,ARCHIVELOG日志已经达到99.9%了。造成归档满的原因是因为有一个用户在做大量更新操作,由于更新操作产生大量重做日志, 归档日志切换频繁。解决方法是要把大量归档日志清除掉! 有两种方式可以解决该问题。 一使用RMAN清除归档日志。 二修改闪回恢复区的大小DB_RECOVERY_FILE_DEST_SIZE。

第一种使用RMAN清除归档日志。

C:\Documents and Settings\Administrator>rman

RMAN> connect target system/sys@orcl

注:system为oracle用户,myoracle为oracle用户密码,orcl为连接的数据库名称SID。

RMAN> crosscheck archivelog all;

RMAN> delete noprompt expired archivelog all;

注:删除过期的归档

这样就把归档文件删除了。再进入sqlplus 查看ARCHIVELOG日志使用率!

第二种方法就是增大闪回恢复区的大小。如下:

SQL>alter system set DB_RECOVERY_FILE_DEST_SIZE=8G;

在归档数据中要制定备份策略。以免造成该问题。 configure retention policy to recovery window of 15 days; 或者在备份时删除日志信息。

DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7'; //删除七天前的归档

DELETE ARCHIVELOG FROM TIME 'SYSDATE-7'; //删除七天到现在的归档

CREATE OR REPLACE TRIGGER DDL_AUDIT AFTER CREATE OR ALTER OR DROP OR RENAME
on DATABASE
declare
TR_N number;
STEXT CLOB := NULL;
TR_SQL_TEXT ORA_NAME_LIST_T;
BEGIN
IF ora_dict_obj_owner  IN ('sys')   then

BEGIN
           TR_N := ORA_SQL_TXT(TR_SQL_TEXT);

FOR I IN 1 .. TR_N LOOP
             STEXT := STEXT || TR_SQL_TEXT(I);
           END LOOP;

EXCEPTION WHEN OTHERS THEN
           null;
END;

insert into WIIDICT.wii_db_log_ddl values
(sysdate,
SYS_CONTEXT('USERENV','DB_NAME'),
user,
nvl(SYS_CONTEXT('USERENV','OS_USER'),'-'),
nvl(SYS_CONTEXT('USERENV','TERMINAL'),'-'),
nvl(SYS_CONTEXT('USERENV','HOST'),'-'),
NVL(ora_dict_obj_name,'-'),
NVL(ORA_SYSEVENT,'-'),
NVL(ora_dict_obj_type,'-'),
NVL(ora_dict_obj_owner,'-'),
STEXT
);
commit;
end if;
exception when others then
null;
END;

Oracle常用文档整理相关推荐

  1. 【MOS】中文文档列表 - Oracle Database (文档 ID 1533057.1)

    中文文档列表 - Oracle Database (文档 ID 1533057.1) 类型: 状态: 上次主更新: 上次更新: ANNOUNCEMENT PUBLISHED 2017-2-23 201 ...

  2. 经典的ORACLE培训文档

    经典的ORACLE培训文档1 数据库的安全性.完整性.并发控制和恢复 为了保证数据库数据的安全可靠性和正确有效,DBMS必须提供统一的数据保护功能.数据保护也为数据控制,主要包括数据库的安全性.完整性 ...

  3. word服务器草稿位置有必要更改么,如何改变WIN10常用文档的默认位置?真的有必要更改吗?...

    我们都知道,安装完Window系统后,系统会默认生成一些常用文件夹,方便你分门别类存储文件.例如"我的文档"文件夹,当你用美图秀秀美化完自拍照时,系统会自动建议你将图片保存在图片文 ...

  4. 将Html文档整理为规范XML文档

    有多种方式可以在.NET 平台进行HTML文件解析.数据提取,其中最简单.稳妥的办法是先使用工具将Html文档整理成XML文档,再通过XML Dom模型或XPath灵活地进行数据处理.SGML便是一个 ...

  5. 互联网产品设计常用文档类型-BRD、MRD、PRD、FSD

    互联网产品设计常用文档类型-BRD.MRD.PRD.FSD 摘自:互联网产品设计常用文档类型-BRD.MRD.PRD.FSD 2017-03-16 1 BRD Business Requirement ...

  6. django+nginx+uwsgi项目部署文档整理

    django+nginx+uwsgi项目部署文档整理 参考文章:https://blog.csdn.net/qq_42314550/article/details/81805328 一.python安 ...

  7. 连载三:Oracle升级文档大全

    (共33篇干货文章,建议收藏并在PC端打开) Oracle 11203->11204.6小版本物理升级方案 https://www.modb.pro/doc/190 OEM CC 12.1.0. ...

  8. NodeJS-001-Nodejs学习文档整理(转-出自http://www.cnblogs.com/xucheng)

    Nodejs学习文档整理 http://www.cnblogs.com/xucheng/p/3988835.html 1.nodejs是什么: nodejs是一个是javascript能在后台运行的平 ...

  9. oracle联机文档使用,Sqlplus 联机文档学习

    Oracle联机文档 [原文] Starting SQL*Plus Command-line The SQL*Plus executable is usually installed in $ORAC ...

  10. 2503平台GPS MT3333秒定参考文档整理 - MTK物联网在线解答 - 技术论坛

        2503平台GPS MT3333秒定参考文档整理 [DESCRIPTION] 以下是目前整理的给客户参考的2503秒定测试及GPS介绍的文档,其中均可在DCC上下载. [SOLUTION] 2 ...

最新文章

  1. 浅谈电量传感器在数据中心不间断电源中的应用
  2. mysql 设置按天分表_MySQL 优化实战记录
  3. python 常用包_Python常用指引
  4. 约瑟夫环(简单版)c语言解决
  5. SQL查询语句-返回名称的分类
  6. vim的ex模式介绍
  7. IDEA连接Spark集群执行Scala程序
  8. 干货 | 外文文献哪里找?八大网站免费下载!
  9. c语言汉字转拼音,c语言汉字转拼音函数源码
  10. SYD8821或SYD8811连接《SYDTEK Studio》异常状况说明
  11. 伴雨夜谈【即便大雨倾盆,也无法击起心中的波澜】
  12. 二、伊森商城 环境 虚拟机配置 p3
  13. 关于LPC21**系列串口初始化已知晶振频率 求U0DLL和U0DLM 重点注意M P 和分频倍率n
  14. 通过安卓逆向来学习安卓开发
  15. 计算机网络技术课程答案网课,《计算机网络技术》大学生网课答案.docx
  16. vue展示日历 考勤展示_基于element-ui的日历显示当月考勤情况
  17. USACO健康的荷斯坦奶牛(DFS,二进制暴力枚举)
  18. 哈工大软件构造实验2
  19. Java编程之实现数字化的连连看
  20. Ulink2升级至V2.03

热门文章

  1. python——字符串练习:句子反转(小米笔试题)
  2. Halcon 错误 提示 2021 System clock has been set back 解决方法
  3. winrar命令行加压解密
  4. 千兆网线 双机互联交叉线
  5. 一文了解啤酒、葡萄酒、黄酒的种类
  6. C++使用system( “pause “);来暂停黑窗口
  7. 番茄花园域名转向Google
  8. [codeforces 760B]Frodo and pillows
  9. spark ml pipelines
  10. LeetCode-----第二题-----两数相加