数据库与具有不同编号的表合并。列

时间:2012-07-13 11:25:18

标签: oracle merge

这是一个场景。 我的数据库中有大约300个表,我想在我的数据库中合并另一个数据库。两个数据库都具有相同的表,但数据类型和列数不同。    现在如何将数据从其他数据库转换到我的数据库?

例如

db1: Table T1(col1 int,col2 char,......,col31 int)
db2: Table T1(col1 int,col2 char,......,col31 int,col32 char,col33 char )

由于数据类型和列数没有变化,我无法使用 “插入db1.tbl  select * from db2.tbl“。

我不想为每个表创建脚本。救救我!!!

1 个答案:

答案 0 :(得分:0)

每天早上我都会将大量的表从生产数据库复制到我的数据仓库中。这是我在每次截断+插入之前运行的“检查和修复”过程。

procedure check_and_fix_table(p_naam in varchar2)
  /**
   * check if columns have changed on PROD and create and execute the matching ALTER TABLE statement
   */
  is

    v_coltype varchar2(100);
    v_sql     varchar2(200);

    function check_column(p_column in varchar2)
    return boolean
    is
        v_dummy number;
    begin
        select 1 into v_dummy
        from   user_tab_cols tc
        where  tc.table_name = upper(p_naam)
        and    tc.column_name = p_column;

        return true;
    exception
        when no_data_found then return false;
    end;

  begin
    -- loop through all columns that are altered (if nothing altered, then nothing will happen
    for i in (select tc.column_name
              ,      tc.data_type
              ,      tc.data_length
              ,      tc.data_precision
              from   user_tab_cols@DB_LINK_TO_PRODUCTION tc
              where  tc.table_name = upper(p_naam)
              and    tc.column_name not like 'SYS_NC%' -- These columns are created by oracle for function based indexes 
              minus
              select tc.column_name
              ,      tc.data_type
              ,      tc.data_length
              ,      tc.data_precision
              from   user_tab_cols tc
              where  tc.table_name = upper(p_naam))
    loop
        -- create column type
        if i.data_type in ('CHAR','VARCHAR2') then
            v_coltype := i.data_type||'('||i.data_length||')';
        elsif i.data_type = 'NUMBER' then
            if i.data_precision is not null then
               v_coltype := i.data_type||'('||i.data_precision||')';
            else
               v_coltype := i.data_type;
            end if;
        else -- DATE, CLOB, BLOB, etc
            v_coltype := i.data_type;
        end if;

        -- check if the column is altered or added
        if check_column(i.column_name) then
            -- execute the ALTER TABLE to fix the column       
            v_sql := 'alter table '||p_naam||' modify '||i.column_name||' '||v_coltype;
        else
            -- add new column
            v_sql := 'alter table '||p_naam||' add '||i.column_name||' '||v_coltype;
        end if;
        execute immediate v_sql;

        -- logging change
        prc_log(c_procedureid, 1, p_naam||' changed. Fixed by executing: '||v_sql);
    end loop;
  exception
    when others then 
      prc_log(c_procedureid, 3, 'Error at copy_package.check_and_fix_table - '||substr(sqlerrm, 0, 1900));
  end;

然后在我的主程序中我像这样使用它(其中p_naam是作为参数传递给程序的表名):

check_and_fix_table(p_naam);

-- full copy of table from PROD
execute immediate 'truncate table ' || p_naam;
execute immediate 'insert /*+append*/ into ' || p_naam || ' select * from ' || p_naam || '@DB_LINK_TO_PRODUCTION';

希望这会有所帮助:)