2012-07-13 49 views
1

這是一個場景。 我在我的數據庫中有大約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」。

我不想爲每個表格創建腳本。幫幫我 !!!

+2

你能保證具有相同名稱的列是相同類型的? – martin 2012-07-13 11:27:32

+0

你只想合併來自兩個數據庫的數據嗎? 如果是這樣,並且您碰巧擁有一個領先的數據庫(具有適當的列和類型的數據庫),您可以創建一個通用腳本。該腳本可以轉換類型,剝離不可用的列或爲以前不存在的列添加空值/默認值。 – Deruijter 2012-07-13 13:25:29

+0

如果@ martin正確,並且您不能保證列具有相同的名稱或相同的順序,那麼您需要手動執行此操作。如果可以的話,你可以創建一個大量過度複雜的動態腳本。 – Ben 2012-07-14 09:11:09

回答

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 [email protected]_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'; 

希望這有助於:)

+0

嗯,OP專門使用了單詞合併。 'truncate'對合並沒有幫助。 – Ben 2012-07-14 09:08:17

+0

因此,您使用合併而不是截斷插入。這不是重點。但我想這不是OP正在尋找的東西。 – winkbrace 2012-07-14 14:17:54

相關問題