数据库架构(源和目标)非常大(每个数据库都有350多个表)。我已经完成了将这两个表合并为一个的任务。数据本身(表中的内容)必须迁移。我必须小心,在合并架构之前或合并架构时,主键没有重复输入。有没有人做过这样的事情并且能够向我提供他的解决方案,或者有人可以帮助我获得完成任务的方法?我的方法都失败了,我的顾问只是告诉我要在线获得帮助:/
对我来说:
我尝试使用“all_constraints”表从数据库中获取所有pk。

SELECT cols.table_name, cols.column_name, cols.position, cons.status, cons.owner 
FROM all_constraints cons, all_cons_columns cols 
WHERE cols.owner = 'DB' 
AND cons.constraint_type = 'P'   
AND cons.constraint_name = cols.constraint_name 
AND cons.owner = cols.owner 
ORDER BY cols.table_name, cols.position; 
我还“知道”主键必须有序列才能为其添加值:
CREATE SEQUENCE seq_pk_addition 
MINVALUE 1 
MAXVALUE 99999999999999999999 
START WITH 1 
INCREMENT BY 1 
CACHE 20; 
因为如果涉及pl/sql(或一般来说是sql),我是菜鸟
那么下一步我应该怎么做? :/

Here is a link for an ERD of the database: https://ufile.io/9tdoj

virus scan: https://www.virustotal.com/#/file/dbe5f418115e50313a2268fb33a924cc8cb57a43bc85b3bbf5f6a571b184627e/detection

请您参考如下方法:

如我所愿,我准备了一个动态代码,您可以尝试使用源表和目标表获取数据merged。逻辑如下:

步骤1:从SOURCE模式获取所有表名。在下面的查询中,您可能需要分别替换架构(所有者)名称。为了进行测试,我只使用了1张表,因此在运行它时,请删除表名筛选子句。

步骤2:获取表的约束列名称。这用于准备ON子句,稍后将其用于MERGE语句。

步骤3:获取表的不受限制的列名。在使用UPDATE时,它将在MERGE子句中使用。

步骤4:当数据与insert语句的ON条件不匹配时,准备MERGE列表。

阅读我的内联注释以了解每个步骤。

CREATE OR REPLACE PROCEDURE COPY_TABLE 
AS 
Type OBJ_NME is table of varchar2(100) index by pls_integer; 
 
--To hold Table name 
v_obj_nm OBJ_NME ; 
 
--To hold Columns of table 
v_col_nm OBJ_NME; 
 
v_othr_col_nm OBJ_NME; 
on_clause VARCHAR2(2000); 
upd_clause VARCHAR2(4000); 
cntr number:=0; 
v_sql VARCHAR2(4000); 
 
col_list1  VARCHAR2(4000); 
col_list2  VARCHAR2(4000); 
col_list3  VARCHAR2(4000); 
col_list4  varchar2(4000); 
col_list5  VARCHAR2(4000); 
col_list6  VARCHAR2(4000); 
col_list7  VARCHAR2(4000); 
col_list8  varchar2(4000); 
 
BEGIN 
 
--Get Source table names 
SELECT OBJECT_NAME 
BULK COLLECT INTO v_obj_nm 
FROM all_objects  
WHERE owner LIKE  'RU%' -- Replace `RU%` with your Source schema name here 
AND object_type = 'TABLE' 
and object_name ='TEST'; --remove this condition if you want this to run for all tables 
 
FOR I IN 1..v_obj_nm.count 
loop 
--Columns with Constraints  
  SELECT column_name 
  bulk collect into v_col_nm  
  FROM user_cons_columns 
  WHERE table_name = v_obj_nm(i);   
 
--Columns without Constraints remain columns of table 
SELECT * 
BULK COLLECT INTO v_othr_col_nm 
from ( 
      SELECT column_name  
      FROM user_tab_cols 
      WHERE table_name = v_obj_nm(i) 
      MINUS 
      SELECT column_name   
      FROM user_cons_columns 
      WHERE table_name = v_obj_nm(i)); 
 
--Prepare Update Clause   
 FOR l IN 1..v_othr_col_nm.count 
  loop 
   cntr:=cntr+1; 
   upd_clause := 't1.'||v_othr_col_nm(l)||' = t2.' ||v_othr_col_nm(l);     
   upd_clause:=upd_clause ||' and ' ; 
 
   col_list1:= 't1.'||v_othr_col_nm(l) ||','; 
   col_list2:= col_list2||col_list1;    
 
   col_list5:= 't2.'||v_othr_col_nm(l) ||','; 
   col_list6:= col_list6||col_list5; 
 
   IF (cntr = v_othr_col_nm.count) 
   THEN  
    --dbms_output.put_line('YES'); 
     upd_clause:=rtrim(upd_clause,' and'); 
     col_list2:=rtrim( col_list2,','); 
     col_list6:=rtrim( col_list6,','); 
   END IF; 
     dbms_output.put_line(col_list2||col_list6);  
   --dbms_output.put_line(upd_clause); 
   End loop; 
  --Update caluse ends      
 
   cntr:=0; --Counter reset   
 
 --Prepare ON clause   
  FOR k IN 1..v_col_nm.count 
  loop 
   cntr:=cntr+1; 
   --dbms_output.put_line(v_col_nm.count || cntr); 
   on_clause := 't1.'||v_col_nm(k)||' = t2.' ||v_col_nm(k);     
   on_clause:=on_clause ||' and ' ; 
 
   col_list3:= 't1.'||v_col_nm(k) ||','; 
   col_list4:= col_list4||col_list3;     
 
   col_list7:= 't2.'||v_col_nm(k) ||','; 
   col_list8:= col_list8||col_list7;     
 
   IF (cntr = v_col_nm.count) 
   THEN  
    --dbms_output.put_line('YES'); 
    on_clause:=rtrim(on_clause,' and'); 
    col_list4:=rtrim( col_list4,','); 
    col_list8:=rtrim( col_list8,','); 
   end if; 
 
   dbms_output.put_line(col_list4||col_list8); 
 -- ON clause ends 
 
 --Prepare merge Statement 
 
    v_sql:= 'MERGE INTO '|| v_obj_nm(i)||' t1--put target schema name before v_obj_nm 
              USING (SELECT * FROM '|| v_obj_nm(i)||') t2-- put source schema name befire v_obj_nm here  
              ON ('||on_clause||') 
              WHEN MATCHED THEN 
              UPDATE 
              SET '||upd_clause ||               
              ' WHEN NOT MATCHED THEN 
              INSERT   
              ('||col_list2||',' 
                ||col_list4|| 
              ') 
              VALUES 
              ('||col_list6||',' 
                ||col_list8||           
               ')'; 
 
      dbms_output.put_line(v_sql);    
      execute immediate v_sql; 
  end loop;     
End loop; 
END; 
/ 

执行:
exec COPY_TABLE 

输出:
anonymous block completed 

PS:我已经用2列的表进行了测试,其中我有唯一的键约束。表的DDL如下:

最后,我希望您能理解我的代码(您是菜鸟)并在上述条件无法满足您的要求时实现类似的操作。
 CREATE TABLE TEST 
       (    COL2 NUMBER,  
            COLUMN1 VARCHAR2(20 BYTE),  
            CONSTRAINT TEST_UK1 UNIQUE (COLUMN1)   
       ) ; 


评论关闭
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!