移动一个表到另一个schema的方法

可以有以下几种常用的办法:
1、expdp/impdp

2、ctas + parallel + nologin

第二种方法要注意主键在新表是没有创建的

NOT NULL constraints that
were implicitly created by Oracle Database on columns of the selected
table (for example, for primary keys) are not carried over to the new
table.

http://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_7002.htm

3、exchange partition

以下针对第三种方法进行测试:
创建big_table脚本来自Oracle Database 9i10g11g编程艺术深入数据库体系结构(第2版),转换方式:普通表A.A->分区表A.A_TEMP->普通表B.B
1.创建测试表:

[email protected]> create table big_table
  2  as
  3  select rownum id, a.OWNER, a.OBJECT_NAME, a.SUBOBJECT_NAME, a.O  3  
  3  select rownum id, a.OWNER, a.OBJECT_NAME, a.SUBOBJECT_NAME, a.OBJECT_ID, a.DATA_OBJECT_ID
  4    from all_objects a
  5   where 1=0
  6  /
Table created.
Elapsed: 00:00:00.09
[email protected]> alter table big_table nologging;
Table altered.
Elapsed: 00:00:00.01
[email protected]> declare
  2      l_cnt number;
  3      l_rows number := &1;
  4  begin
  5      insert /*+ append */
  6      into big_table
  7      select rownum, a.OWNER, a.OBJECT_NAME, a.SUBOBJECT_NAME, a.OBJECT_ID, a.DATA_OBJECT_ID
  8        from all_objects a
  9   where rownum <= &1;
 10  
 11      l_cnt := sql%rowcount;
 12  
 13      commit;
 14  
 15      while (l_cnt < l_rows)
 16      loop
 17          insert /*+ APPEND */ into big_table
 18          select rownum+l_cnt, 
 19                 OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID
 20            from big_table
 21           where rownum <= l_rows-l_cnt;
 22          l_cnt := l_cnt + sql%rowcount;
 23          commit;
 24      end loop;
 25  end;
 26  /
Enter value for 1: 8000000
old   3:     l_rows number := &1;
new   3:     l_rows number := 8000000;
Enter value for 1: 8000000
old   9:  where rownum <= &1;
new   9:  where rownum <= 8000000;
PL/SQL procedure successfully completed.
Elapsed: 00:00:07.73
[email protected]> select count(*) from big_table;
  COUNT(*)
----------
   8000000
Elapsed: 00:00:01.86
[email protected]> alter table big_table add constraint big_table_pk primary key(id);
Table altered.
Elapsed: 00:00:38.63
[email protected]> [email protected]> exec dbms_stats.gather_table_stats( user, ‘BIG_TABLE‘, estimate_percent=> 1);
PL/SQL procedure successfully completed.

创建中间表:

[email protected]> CREATE TABLE big_table_temp
   2    PARTITION BY RANGE (id)
   3   (PARTITION id_1 VALUES LESS THAN (MAXVALUE))
   4    AS
   5     SELECT *
   6       FROM big_table
   7      WHERE ROWNUM <= 0;
[email protected]> alter table big_table_temp add constraint pk_big_table_temp_id primary key(id);

为pinfo用户授权:

[email protected]>  grant ALL on big_table to "PINFO";
[email protected]>  grant ALL on big_table_temp to "PINFO";

登录pinfo,创建info同名表:

[email protected]> conn pinfo/admin
Connected.
[email protected]> CREATE TABLE pinfo.big_table
  2  AS
  3     SELECT *
  4       FROM info.big_table
  5      WHERE ROWNUM <= 0;

登录info,将big_table交换至big_table_temp:

[email protected]> conn info/admin
[email protected]> ALTER TABLE big_table_temp EXCHANGE PARTITION id_1 WITH TABLE big_table EXCLUDING INDEXES WITHOUT VALIDATION;
Table altered.
Elapsed: 00:00:00.02
#此处使用了excludeing选项,否则会报 ORA-14098: index mismatch for tables in ALTER TABLE EXCHANGE PARTITION,可以在交换完成以后手动创建索引
[email protected]> select count(*) from big_table;
  COUNT(*)
----------
   0
[email protected]> select count(*) from  info.big_table_temp;
  COUNT(*)
----------
  8000000

登录pinfo,将big_table_temp交换至big_table:

[email protected]> ALTER TABLE info.big_table_temp EXCHANGE PARTITION id_1 WITH TABLE pinfo.big_table EXCLUDING INDEXES WITHOUT VALIDATION;
Table altered.
Elapsed: 00:00:00.01
[email protected]> select count(*) from big_table;
  COUNT(*)
----------
   8000000
Elapsed: 00:00:02.91
[email protected]> select count(*) from  info.big_table_temp;
  COUNT(*)
----------
         0

完成交换几乎是毫秒级的。

也可以反向交换回去:

[email protected]> ALTER TABLE info.big_table_temp EXCHANGE PARTITION id_1 WITH TABLE pinfo.big_table EXCLUDING INDEXES WITHOUT VALIDATION;
[email protected]> conn info/admin
[email protected]> ALTER TABLE big_table_temp EXCHANGE PARTITION id_1 WITH TABLE big_table exCLUDING INDEXES WITHOUT VALIDATION;

以下内容来自asktom,转换方式:普通表A.A->分区表B.B

参考:https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:752030266230

To quickly move big tables between schemas  use EXCHANGE PARTITION feature of Oracle 8i.
for example:
SQL> connect as user "A"
SQL> create table large_table
     (
       a number,
       b char,
       c date
     )
-- just for this example only. :)
SQL> grant ALL on large_table to "B";
SQL> connect as user "B"
SQL> create table large_table 
     (
       a number,  
       b char,    
       c date
     )
     partition by range (a)
     (
       partition dummy values less than (maxvalue)
     )
Then you can use the following command to quickly move 
"A.large_table" to "B.large_table"
SQL> connect as user "B";
SQL> alter table large_table exchange partition dummy
     with table A.large_table;
And return it back to schema A:
SQL> alter table large_table exchange partition dummy
     with table A.large_table;
-- of course, it is the same SQL command
时间: 2024-12-25 13:12:54

移动一个表到另一个schema的方法的相关文章

[SQL]复制数据库某一个表到另一个数据库中

SQL:复制数据库某一个表到另一个数据库中 SELECT * INTO 表1 FROM 表2 --复制表2如果只复制结构而不复制内容或只复制某一列只要加WHERE条件就好了 例子:SELECT * INTO [IMCDB].[dbo].[SysLog] FROM [AimManageDB].[dbo].[SysLog] (将数据库AimManageDB中的SysLog表复制到数据库IMCDB中) 跨服务器复制表 select * INTO [SMSDB].[dbo].[SysLog] FROM

access中根据一个表创建另一个

access中根据一个表创建另一个 SELECT * INTO newTableFROM zD_qlr; SELECT * into mdFROM zd IN 'E:\fz\高阳\大姚\fz\bz\bz.mdb'; insert into 路网1 select * from 路网

oracle 根据一个表生成另一个新表和一个现有表给一个新的表赋值

1,添加表B ,和A表表结构相同(带数据) create table B  as select * from A; 2,添加表B ,和A表表结构相同(不带带数据) create table B  as select * from A where 1=2; 3,存在一个表B和表A的表结构一致,将A中的数据复制给B表 insert into B select * from A; 4,存在一个表B和表A的表结构不一致,将A中的数据复制给B表 insert into B (x1,x2,x3...) se

SQL语句:一个表,通过一个字段查找另外一个字段不相同值

select * from [dbo].[Sys_MemberKey] a where exists(select * from [Sys_MemberKey] b where a.FMachineCode<>'' and a.FKeyID=b.FKeyID and a.FMemberID<>b.FMemberID) 一个相同的表根据一个字段,查找另外一个字段不相同值,经测试可用

SQL查询一个表的总记录数的方法

一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指定列 SQL>SELECT empmo, ename, mgr FROM emp; SQL>SELECT DISTINCT mgr FROM emp; 只显示结果不同的项 4. 查询指定行 SQL>SELECT * FROM emp WHERE job='CLERK'; 5. 使用算术表达式 SQL>SELECT ename, sa

mysql 怎么通过sql语句批量去掉某一个表中某一个字段的多余字符

采用替换,把”<img src="“替换为空格," width="300" height="300" />也替换为空格,曾经在网上看到过这样的SQL,替换字段中字符串中的某些字符 update 表名 set 要修改的字段名= replace(要修改的字段名,‘<img src="’,'') update 表名 set 要修改的字段名= replace(要修改的字段名,‘width="300" hei

sql server从一个数据库复制一个表到另一个数据库的方法

分两步进行:第一步,复制表结构:    在表上面右击-->编写表脚本为:-->Create到-->新查询编辑器窗口,你也可以保存为sql文件, 将新查询编辑器窗口最上面的一句话USE [olddatabase]中的"olddatabase"修改为"newdatabase",其中olddatabase为源数据库名,newdatabase为目标数据库名,点击上面的"执行"按钮,这样,表结构复制完毕:第二步,复制表数据:    在&q

sql 根据一个表更新 另一个表的例子及可能遇到的问题

例子: update a set a.name=b.name1 from a,b where a.id=b.id 例子延伸:更新的时候会把字符串 转为科学计数法  怎么办? 答:用 cast 转换一下 ,或者双cast update LoaneeExpand  set LoaneeExpand.phone=cast(cast(tt.PHONE as decimal(18,0))  as  nvarchar(50))  from LoaneeExpand ,tt  where  LoaneeExp

SqlSever基础 给一个数据库中的一个表中的一个指定的列赋值

1 code 1 create database helloworld2 2 3 use helloworld2 4 5 create table Teacher2 6 ( 7 ShengHao nvarchar(20) not null, 8 Id nvarchar(10) default(0) --你不给我赋值的话,我就默认为0,可以为空哦 9 ) 10 11 --插入 12 insert Teacher2(ShengHao) 13 values('元始天尊') 14 --查看 15 sel