在线重定义(Rdefine Table online)

时间:2021-02-17 15:46:13

二、        概念理解

在线重定义用于对表的逻辑或者物理结构的修改,而且在修改时不影响表的可用性与传统方式相比。当一个表被重定义时,会被锁定为exclusive mode很短一段时间,这段时间的长短取决于表的依赖关系,和复杂度,而且这些对用户来说都是透明的。

注:如果对重定义期间表是否可用没有要求的话,可以使用更简单的方式。使用ALTER TABLE MOVE这个命令。

在线重定义时基于物化视图的,在同步数据时就是应用物化视图日志刷新物化视图,使得临时表中的数据和原表中的数据保持一致。

三、        过程设计

在线重定义需要用到一个系统包DBMS_REDEFINITION。在线重定义表大概可以分为以下几个步骤

1.       选择重定义方式

By key:可以选择一个primary key or pseudo-primary key用于在线重定义。对于这种方式来说,必须保证重定义前后表的primary key 是相同的。这种方式也是默认的方式。

By roweid:对于没有键值可以使用的表可以使用这种方式。这种方式要用到一个隐藏列M_ROW$$,会将该列添加到被重定义的表中。建议在重定义完成之后,将该列删除或者标志为不可用。索引组织表不能使用这种方式。

2.       检验是否可以被重定义

在重定义表之前要先检查该表是否能够被重定义。这里要用到DBMS_REDEFINITION包中的一个存储过程CAN_REDEF_TABLE 。如果不能够被重定义,该存储过程会返回一个错误表明不能被重定义的原因。

3.       创建临时表

创建一个临时表(和被重定义的表属于相同的schema),该表的结构和物理存储即为你希望重定义后的表的结构。这创建临时表时不需要创建所有的indexes, constraints, grants, triggers在后面第六步执行cope的时候会将被重定义表的依赖的所有对象全部copy。

4.       修改并行度

这一步并不是必须的,如果要被重定义的表非常大。为了提高执行query和DML命令的性能,则可以使用一下命令,更改并行度。

alter session force parallel dml parallel degree-of-parallelism;

alter session force parallel query parallel degree-of-parallelism;

5.       开始重定义

这一步要用到DBMS_REDEFINITION 包的一个存储过程START_REDEF_TABLE这个存储过程有个参数col_mapping参数。这一步的重点内容就是如何构建映射列参数字符串,语法如下:

[expression]  column_name

Expression:表示被重定义表中要修改的列,重定义后结果会被存储到对应的column_name列中。

column_name:为临时表中的列,和Expression中的列相对应。

比如:我想在被重定义表中的列override 想要被修改为override_commission而且该列的值修改后的表中要增长0.2%则对应的映射列写法如下:

override *1.2%  override_commission

注:如果col_mapping参数中指定‘*’或者null值时。默认将被重定义表中所有的列中的数据全部存储到临时表中相同名称的列中。

如果START_REDEF_TABLE因为任何原因执行失败都需要执行以下ABORT_REDEF_TABLE存储过程,不然下次重新执行的时候会失败。

由于这一步中涉及到数据的copy会等待一段时间,但这个时间内被重定义的表仍然是可以使用的。

6.    拷贝有依赖关系的objects和statistics

将有依赖关系的objects(indexes, constraints, grants, triggers)和statistics从被重定义的表拷贝到临时表中。这里有两种方法可以使用。

a)        Method 1: Automatically Creating Dependent Objects

使用DBMS_REDEFINITION包的COPY_TABLE_DEPENDENTS 存储过程,自动的创建相关联的objects到临时表中。如果在拷贝相关联的对象到临时表的过程中出现了错误,可以以通过检查的COPY_TABLE_DEPENDENTS 存储过程的num_errors这个输出参数,来查看错误。

在这个存储过程中有一个参数ignore_errors 如果这个参数被设置为TRUE则如果在执行COPY_TABLE_DEPENDENTS 的过程中出现错误,则不会忽略该错误继续执行。如果设这为false则如果遇到错误的话,会直接中断运行。

可以通过DBA_REDEFINITION_ERRORS这个视图查询到拷贝过程中出现错误的object。然后通过手动创建他。

出现错误的原因包括:

缺少系统资源 表的逻辑结构发生变化,需要重新编译相关联的对象

如果失败之后你还行继续执行,可以再次重新运行COPY_TABLE_DEPENDENTS这个存储过程,已经被成功拷贝的objects不需要再次copy。

b)        Method 2: Manually Creating Dependent Objects

手动创建相关联对象时必须使用到REGISTER_DEPENDENT_OBJECT 这个存储过程。DBA_REDEFINITION_OBJECTS 这个视图会明确的说明有哪些关联对象需要被copy到临时表中。

7.       同步数据

在调用FINISH_REDEF_TABLE 完成重定义之前,可以先调用SYNC_INTERIM_TABLE对临时表中的数据和原表中的数据同步一下。因为在START_REDEF_TABLE执行后到FINISH_REDEF_TABLE存储过程执行前,在这期间被重定义的原表数据又会被修改很多次。

执行FINISH_REDEF_TABLE存储过程是原表被锁定为exclusive mode 的时间,取决于你是否执行了SYNC_INTERIM_TABLE这个存储过程。

8.       结束重定义

在这个过程需要调用FINISH_REDEF_TABLE这个存储过程。到这一步为止,原表和临时表中的数据就完全一致了。现在就只差表名了,通过这一步可以在数据字典中将原表和临时表调换一下,这样原表就拥有了现在临时表的所有数据和结构,也就达到了重定义的目的。这也就是为什么在线重定义只需要锁定原表很短的时间就可以完成重定义。

9.       禁用隐藏列

如果重定义使用的方式是rowid 而且你的COMPATIBLE 参数设置为比10.1或者更低的话。在完成重定义之后需要禁用隐藏列M_ROW$$这点在前面提到过。

使用以下命令:ALTER TABLE table_name SET UNUSED (M_ROW$$);

如果COMPATIBLE 参数设置为10.2或者更高隐藏列会自动被设置为不可用。如果你愿意,可以在完成重定义之后将隐藏列删除。

第二部分 .       技术概述

一、        实验

下面是官方文档中的几个实验,由于上面已经将每一步所要做的内容都详细阐述下面实验时就不一一说明。

1.       Redefines a table by key

a)        实验目标

将test表添加一新列t4,t3列重定义之后值变为t3+1,test表的结构如下:

b)        创建实验表

SQL> create table test(

2  t1 number primary key,

3  t2 varchar2(10),

4  t3 number);

c)         检验是否能被重定义

SQL> begin

2  DBMS_REDEFINITION.CAN_REDEF_TABLE('scott','test',DBMS_REDEFINITION.CONS_USE_PK);

3  end;

4  /

PL/SQL procedure successfully completed.

d)        创建临时表

SQL> create table init_test(

2  t1 number primary key,

3  t2 varchar2(10),

4  t3 number,

5  t4 number);

e)        开始重定义

SQL> begin

2   DBMS_REDEFINITION.START_REDEF_TABLE('scott','test','init_test','t1 t1,t2 t2,t3+1 t3,0 t4',dbms_redefinition.cons_use_pk);

3  end;

4  /

PL/SQL procedure successfully completed

注:实验时发现这一步只能以sys权限完成,即使scott用户拥有DBMS_REDEFINITION包的执行权限。

f)          拷贝关联对象

SQL> declare

2  num_errors PLS_INTEGER;

3  BEGIN

4  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('scott','test','init_test',DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);

5  end;

6  /

可以通过下面命令查看,有哪些objects创建到临时表时失败。

SQL> select object_name, base_table_name, ddl_txt from DBA_REDEFINITION_ERRORS;

OBJECT_NAME                    BASE_TABLE_NAME

------------------------------ ------------------------------

DDL_TXT

--------------------------------------------------------------------------------

SYS_C005163                    TEST

CREATE UNIQUE INDEX "SCOTT"."TMP$$_SYS_C0051630" ON "SCOTT"."INIT_TEST" ("T1")

SYS_C005163                    TEST

ALTER TABLE "SCOTT"."INIT_TEST" ADD CONSTRAINT "TMP$$_SYS_C0051630" PRIMARY KEY

这里,由于上面我们在临时表中已经创建了主键,所以从原表到临时表进行拷贝是报错。

g)        同步临时表中的数据

SQL> begin

2  DBMS_REDEFINITION.SYNC_INTERIM_TABLE('scott','test','init_test');

3  end;

4  /

PL/SQL procedure successfully completed.

h)        结束重定义

SQL> begin

2  DBMS_REDEFINITION.FINISH_REDEF_TABLE('scott','test','init_test');

3  end;

4  /

PL/SQL procedure successfully completed.

i)          确认目标是否达到

SQL> desc scott.test;

Name                                      Null?    Type

----------------------------------------- -------- ----------------------------

T1                                        NOT NULL NUMBER

T2                                                 VARCHAR2(10)

T3                                                 NUMBER

T4                                                 NUMBER

可以看到test表现在的结构即为我们所期望的。下面在看一下数据是否完整,并且达到要求。

SQL> select * from scott.test;

T1 T2                 T3         T4

---------- ---------- ---------- ----------

1 a                   3          0

2 b                   4          0

3 c                   5          0

在看一下,现在的临时表中的数据。

SQL> select * from scott.init_test;

T1 T2                 T3

---------- ---------- ----------

1 a                   2

2 b                   3

3 c                   4

最后你也可以选择将临时表删除,以清理环境。

SQL> drop table scott.init_test;

Table dropped.

2.       Redefines a table by rowid

a)        实验目标

一举test表中的empno列进行range分区,deptno列。

b)        创建实验表

这里表名我就不该了依然是test(上次的实验表都已被我清除)

SQL> create table test as select empno,ename,job,sal,deptno from emp;

Table created.

看一下表的结构。

SQL> desc test;

Name                                      Null?    Type

----------------------------------------- -------- ----------------------------

EMPNO                                              NUMBER(4)

ENAME                                              VARCHAR2(10)

JOB                                                VARCHAR2(9)

SAL                                                NUMBER(7,2)

DEPTNO                                             NUMBER(2)

这里我直接从scott用户下的emp表创建一个test表

c)         检查是否能够被重定义

SQL> BEGIN

2  DBMS_REDEFINITION.CAN_REDEF_TABLE('scott','test',DBMS_REDEFINITION.CONS_USE_ROWID);

3  END;

4  /

d)        创建临时表

SQL> Create table init_test(

EMPNO NUMBER(4),

ENAME VARCHAR2(10),

JOB VARCHAR2(9),

SAL NUMBER(7,2)

)

PARTITION BY RANGE(empno)

(PARTITION emp1000 VALUES LESS THAN (7800) TABLESPACE users,

PARTITION emp2000 VALUES LESS THAN (MAXVALUE) TABLESPACE users);

2    3    4    5    6    7    8    9

Table created.

e)        开始重定义

SQL> BEGIN

2  DBMS_REDEFINITION.START_REDEF_TABLE('scott','test','init_test','empno empno, ename ename,job job,sal sal',DBMS_REDEFINITION.CONS_USE_ROWID);

3  END;

4  /

PL/SQL procedure successfully completed.

f)          拷贝关联对象

SQL> DECLARE

2  num_errors PLS_INTEGER;

3  BEGIN

4  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('scott','test','init_test',DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);

5  END;

6  /

PL/SQL procedure successfully completed.

g)        同步临时表中的数据

SQL> BEGIN

2  DBMS_REDEFINITION.SYNC_INTERIM_TABLE('scott','test','init_test');

3  END;

4  /

PL/SQL procedure successfully completed.

h)        结束重定义

SQL> BEGIN

2  DBMS_REDEFINITION.FINISH_REDEF_TABLE('scott','test','init_test');

3  END;

4  /

PL/SQL procedure successfully completed.

i)          确认是否达到重定义的目标

查看test表中的数据

SQL> SELECT * FROM SCOTT.TEST;

EMPNO ENAME      JOB              SAL

---------- ---------- --------- ----------

7369 SMITH      CLERK            800

7499 ALLEN      SALESMAN        1600

7521 WARD       SALESMAN        1250

7566 JONES      MANAGER         2975

7654 MARTIN     SALESMAN        1250

7698 BLAKE      MANAGER         2850

7782 CLARK      MANAGER         2450

7788 SCOTT      ANALYST         3000

7839 KING       PRESIDENT       5000

7844 TURNER     SALESMAN        1500

7876 ADAMS      CLERK           1100

7900 JAMES      CLERK            950

7902 FORD       ANALYST         3000

7934 MILLER     CLERK           1300

14 rows selected.

可以看到数据都完整的存在,且deptno列被删除

现在确认下分区是否完成,查看一下表的结构。

SQL> select dbms_metadata.get_ddl('TABLE','TEST','SCOTT') FROM DUAL;

DBMS_METADATA.GET_DDL('TABLE','TEST','SCOTT')

--------------------------------------------------------------------------------

CREATE TABLE "SCOTT"."TEST"

(    "SYS_C00005_12092700:08:31$" VARCHAR2(255),

"EMPNO" NUMBER(4,0),

"ENAME" VARCHAR2(10),

"JOB" VARCHAR2(9),

"SAL" NUMBER(7,2)

) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE(

BUFFER_POOL DEFAULT)

TABLESPACE "USERS"

PARTITION BY RANGE ("EMPNO")

(PARTITION "EMP1000"  VALUES LESS THAN (7800)

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

TABLESPACE "USERS" NOCOMPRESS ,

PARTITION "EMP2000"  VALUES LESS THAN (MAXVALUE)

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

TABLESPACE "USERS" NOCOMPRESS )

可以看到两个分区也已经成功添加。

j)          禁用隐藏列

SQL> SELECT * FROM V$VERSION;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE    10.2.0.1.0      Production

前面说过如果数据库版本在10.2或者更高的版本则在重定义结束之后会自动禁用隐藏列,所以这里就不

3.       Demonstrates redefinition with object datatypes.

这个式样我们使用scott用户下的emp表作为实验表。先看一下emp表的结构:

SQL> desc emp

Name                                      Null?    Type

----------------------------------------- -------- ----------------------------

EMPNO                                     NOT NULL NUMBER(4)//主键

ENAME                                              VARCHAR2(10)

JOB                                                VARCHAR2(9)

MGR                                                NUMBER(4)

HIREDATE                                           DATE

SAL                                                NUMBER(7,2)

COMM                                               NUMBER(7,2)

DEPTNO                                             NUMBER(2)

a)        创建一个列对象类型

4.       Demonstrates redefinition with manually registered dependent objects.

在这个实验中我们模拟手动在临时表中创建相关联的对象并将原表中的t3列删除。

a)        创建实验表

SQL> create table t(

2  t1 number primary key,

3  t2 varchar2(10) constraint uq_t unique,

4  t3 number);

Table created.

查看一下现在表中的constraint和index

SQL> select CONSTRAINT_NAME,CONSTRAINT_TYPE,OWNER from user_constraints

2  where table_name='T';

CONSTRAINT_NAME                C OWNER

------------------------------ - ------------------------------

SYS_C005217                    P SCOTT//主键约束由于前面我们没有指定名称,所以系统自动生成

UQ_T                           U SCOTT//唯一性约束

SQL> r

1  select INDEX_NAME,INDEX_TYPE,TABLE_OWNER from user_indexes

2* where table_name='T'

INDEX_NAME                     INDEX_TYPE                  TABLE_OWNER

------------------------------ --------------------------- ------------------------------

SYS_C005217                    NORMAL                      SCOTT//唯一性索引,系统自动为主键列创建

UQ_T                           NORMAL                      SCOTT//唯一性索引

后面我们将在临时表中手动创建唯一性索引,和约束。

插入数据:

SQL> select * from t;

T1 T2                 T3

---------- ---------- ----------

1 a                   1

2 b                   2

3 c                   3

4 d                   4

b)        检验是否能被重定义

SQL> conn / as sysdba

Connected.

SQL> begin

2  dbms_redefinition.can_redef_table('scott','t',dbms_redefinition.cons_use_pk);

3  end;

4  /

PL/SQL procedure successfully completed.

c)         创建临时表

由于我们需要手动创建原表中相应的以来对象,所以在创建临时表时我们可以直接把相关的对象创建出来,也可以等表创建完成后在添加相关对象。

SQL> create table init_t(

2  t1 number primary key,

3  t2 varchar2(10) constraint uq_init_t unique);

Table created.

d)        开始重定义

SQL> begin

2  dbms_redefinition.start_redef_table('scott','t','init_t','t1 t1,t2 t2',dbms_redefinition.cons_use_pk);

3  end;

4  /

PL/SQL procedure successfully completed.

e)        手动Copy相关联对象

使用REGISTER_DEPENDENT_OBJECT将相关对象进行注册。

SQL> begin

2  DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT('scott','t','init_t',dbms_redefinition.cons_constraint,'scott','UQ_T','UQ_INIT_T');

3  end;

4  /

PL/SQL procedure successfully completed.

SQL> begin

2  DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT('scott','t','init_t',dbms_redefinition.cons_index,'scott','UQ_T','UQ_INIT_T');

3  end;

4  /

PL/SQL procedure successfully completed.

f)          Copy剩余的依赖对象

SQL> declare

2  num_errors PLS_INTEGER

3  ;

4  BEGIN

5  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('scott','t','init_t',DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);

6  END;

7  /

PL/SQL procedure successfully completed.

在我们这个实验里其实这一步就没必要了,因为就一个唯一性约束和索引,也已经被手动创建了。如果在实际环境中,除去那些必须手动创建的还会有没有被创建的这步就必须有了。

g)        同步临时表中的数据

SQL> begin

2  DBMS_REDEFINITION.SYNC_INTERIM_TABLE('scott','t','init_t');

3  end;

4  /

PL/SQL procedure successfully completed.

h)        完成重定义

SQL> begin

2  dbms_redefinition.finish_redef_table('scott','t','init_t');

3  end;

4  /

PL/SQL procedure successfully completed.

i)          查看目标是否完成

查看表中数据:

SQL> select * from scott.t;

T1 T2

---------- ----------

1 a

2 b

3 c

4 d

查看索引:

SQL> r

1   select INDEX_NAME,INDEX_TYPE,TABLE_OWNER from user_indexes

2* where table_name='T'

INDEX_NAME                     INDEX_TYPE                  TABLE_OWNER

------------------------------ --------------------------- ------------------------------

SYS_C005219                    NORMAL                      SCOTT

UQ_T                           NORMAL                      SCOTT

查看约束:

SQL> select CONSTRAINT_NAME,CONSTRAINT_TYPE,OWNER from user_constraints

2  where table_name='T';

CONSTRAINT_NAME                C OWNER

------------------------------ - ------------------------------

SYS_C005219                    P SCOTT

UQ_T                           U SCOTT

实验完成。

5.       Redefines a single table partition, moving it to a different tablespace.

在这个实验里,我们模拟将T表中的part02分区从users表空间移动到redef_t表空间。

a)        创建实验表

SQL> create table t(

2  t1 number primary key,

3  t2 varchar2(10))

4  PARTITION BY RANGE (t1)

5  (

6  partition part01 values less than(10) tablespace users,

7  partition part02 values less than(maxvalue) tablespace users);

Table created.

插入数据:(过程略)

SQL> select * from t;

T1 T2

---------- ----------

1 a

2 b

3 c

4 d

5 e

11 aa

22 bb

33 cc

44 dd

55 ee

10 rows selected.

b)        检验是否可以被重定义

SQL> conn / as sysdba

Connected.

SQL> begin

2  dbms_redefinition.can_redef_table('scott','t',dbms_redefinition.cons_use_pk);

3  end;

4  /

PL/SQL procedure successfully completed.

c)         创建临时表

SQL> create table init_t(

2  t1 number primary key,

3  t2 varchar2(10)

4  )

5  PARTITION BY RANGE (t1)(

6  partition part01 values less than(10) tablespace users,

7  partition part02 values less than(maxvalue) tablespace redef_t);

Table created.

d)        开始重定义

SQL> begin

2  dbms_redefinition.start_redef_table('scott','t','init_t','t1 t1,t2 t2',dbms_redefinition.cons_use_pk);

3  end;

4  /

PL/SQL procedure successfully completed.

e)        Copy依赖对象

SQL> declare

2  num_errors PLS_INTEGER

3  ;

4  BEGIN

5  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('scott','t','init_t',DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);

6  END;

7  /

PL/SQL procedure successfully completed.

f)          同步数据

SQL> begin

2

3  DBMS_REDEFINITION.SYNC_INTERIM_TABLE('scott','t','init_t');

4  end;

5  /

PL/SQL procedure successfully completed.

g)        完成重定义

SQL> begin

2  dbms_redefinition.finish_redef_table('scott','t','init_t');

3  end;

4  /

PL/SQL procedure successfully completed.

h)        确定目标是否完成

查看T表的ddl语句

SQL> select dbms_metadata.get_ddl('TABLE','T','SCOTT') from dual;

DBMS_METADATA.GET_DDL('TABLE','T','SCOTT')

--------------------------------------------------------------------------------

CREATE TABLE "SCOTT"."T"

(    "T1" NUMBER,

"T2" VARCHAR2(10),

PRIMARY KEY ("T1")

USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

TABLESPACE "USERS"  ENABLE

) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE(

BUFFER_POOL DEFAULT)

TABLESPACE "USERS"

PARTITION BY RANGE ("T1")

(PARTITION "PART01"  VALUES LESS THAN (10)

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

TABLESPACE "USERS" NOCOMPRESS ,

PARTITION "PART02"  VALUES LESS THAN (MAXVALUE)

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255

STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

TABLESPACE "REDEF_T" NOCOMPRESS )

可以看到,T表的part02分区被成功存放到了redef_t表空间。

二、        实验分析

这里将试中遇到的一些错误和大家分享下

在实验一的e)步出现如下错误:

SQL> BEGIN

2  DBMS_REDEFINITION.START_REDEF_TABLE('scott', 'emp','init_emp','sale*1.2% sale',dbms_redefinition.cons_use_pk);

3  END;

4  /

BEGIN

*

ERROR at line 1:

ORA-01031: insufficient privileges

ORA-06512: at "SYS.DBMS_REDEFINITION", line 50

ORA-06512: at "SYS.DBMS_REDEFINITION", line 1343

ORA-06512: at line 2

原因:不具有权限

解决方案:赋予SYS.DBMS_REDEFINITION的execute权限

三、        实验小结

四、        参考文献

官方文档位置:

BooksèADMèManage TablesèRedefine Table Online

BooksèPL/èDBMS_REDEFINITION

 
 转载:http://blog.itpub.net/26723566/viewspace-753750/